1 2 /* HOW TO COMPILE: 3 4 * 32bit build: 5 gcc -Winline -Wall -g -O -mregnames -maltivec 6 * 64bit build: 7 gcc -Winline -Wall -g -O -mregnames -maltivec -m64 8 9 This program is useful, but the register usage conventions in 10 it are a complete dog. In particular, _patch_op_imm has to 11 be inlined, else you wind up with it segfaulting in 12 completely different places due to corruption (of r20 in the 13 case I chased). 14 */ 15 16 /* 17 * test-ppc.c: 18 * PPC tests for qemu-PPC CPU emulation checks 19 * 20 * Copyright (c) 2005 Jocelyn Mayer 21 * 22 * This program is free software; you can redistribute it and/or 23 * modify it under the terms of the GNU General Public License V2 24 * as published by the Free Software Foundation 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 * Theory of operations: 38 * a few registers are reserved for the test program: 39 * r14 => r18 40 * f14 => f18 41 * I do preload test values in r14 thru r17 (or less, depending on the number 42 * of register operands needed), patch the test opcode if any immediate 43 * operands are required, execute the tested opcode. 44 * XER, CCR and FPSCR are cleared before every test. 45 * I always get the result in r17 and also save XER and CCR for fixed-point 46 * operations. I also check FPSCR for floating points operations. 47 * 48 * Improvments: 49 * a more clever FPSCR management is needed: for now, I always test 50 * the round-to-zero case. Other rounding modes also need to be tested. 51 */ 52 53 /* 54 * Operation details 55 * ----------------- 56 * The 'test' functions (via all_tests[]) are wrappers of single asm instns 57 * 58 * The 'loops' (e.g. int_loops) do the actual work: 59 * - loops over as many arguments as the instn needs (regs | imms) 60 * - sets up the environment (reset cr,xer, assign src regs...) 61 * - maybe modifies the asm instn to test different imm args 62 * - calls the test function 63 * - retrieves relevant register data (rD,cr,xer,...) 64 * - prints argument and result data. 65 * 66 * More specifically... 67 * 68 * all_tests[i] holds insn tests 69 * - of which each holds: {instn_test_arr[], description, flags} 70 * 71 * flags hold 3 instn classifiers: {family, type, arg_type} 72 * 73 * // The main test loop: 74 * do_tests( user_ctl_flags ) { 75 * foreach(curr_test = all_test[i]) { 76 * 77 * // flags are used to control what tests are run: 78 * if (curr_test->flags && !user_ctl_flags) 79 * continue; 80 * 81 * // a 'loop_family_arr' is chosen based on the 'family' flag... 82 * switch(curr_test->flags->family) { 83 * case x: loop_family_arr = int_loops; 84 * ... 85 * } 86 * 87 * // ...and the actual test_loop to run is found by indexing into 88 * // the loop_family_arr with the 'arg_type' flag: 89 * test_loop = loop_family[curr_test->flags->arg_type] 90 * 91 * // finally, loop over all instn tests for this test: 92 * foreach (instn_test = curr_test->instn_test_arr[i]) { 93 * 94 * // and call the test_loop with the current instn_test function,name 95 * test_loop( instn_test->func, instn_test->name ) 96 * } 97 * } 98 * } 99 * 100 * 101 * Details of intruction patching for immediate operands 102 * ----------------------------------------------------- 103 * All the immediate insn test functions are of the form {imm_insn, blr} 104 * In order to patch one of these functions, we simply copy both insns 105 * to a stack buffer, and rewrite the immediate part of imm_insn. 106 * We then execute our stack buffer. 107 * All ppc instructions are 32bits wide, which makes this fairly easy. 108 * 109 * Example: 110 * extern void test_addi (void); 111 * asm(".section \".text\"\n" 112 * " .align 2\n" 113 * " .type test_addi,@function\n" 114 * "test_addi:\n" 115 * " addi\n" 116 * " blr\n" 117 * " .previous\n" 118 * ); 119 * 120 * We are interested only in: 121 * " addi 17, 14, 0\n" 122 * " blr\n" 123 * 124 * In a loop test, we may see: 125 * uint32_t func_buf[2]; // our new stack based 'function' 126 * for imm... // loop over imm 127 * init_function( &func, func_buf ); // copy insns, set func ptr 128 * patch_op_imm16(&func_buf[0], imm); // patch 'addi' insn 129 * ... 130 * (*func)(); // exec our rewritten code 131 * 132 * patch_op_imm16() itself simply takes the uint32_t insn and overwrites 133 * the immediate field with the new value (which, for 'addi', is the 134 * low 16 bits). 135 * 136 * So in the loop test, if 'imm' is currently 9, and p[0] is: 137 * 0x3A2E0000 => addi 17, 14, 0 138 * 139 * after patch_op_imm16(), func_buf[0] becomes: 140 * 0x3A2E0009 => addi 17, 14, 9 141 * 142 * Note: init_function() needs to be called on every iteration 143 * - don't ask me why! 144 */ 145 146 147 /**********************************************************************/ 148 /* Uncomment to enable many arguments for altivec insns */ 149 #define USAGE_SIMPLE 150 151 /* Uncomment to enable many arguments for altivec insns */ 152 //#define ALTIVEC_ARGS_LARGE 153 154 /* Uncomment to enable output of CR flags for float tests */ 155 //#define TEST_FLOAT_FLAGS 156 157 /* Uncomment to enable debug output */ 158 //#define DEBUG_ARGS_BUILD 159 //#define DEBUG_FILTER 160 161 /* These should be set at build time */ 162 //#define NO_FLOAT 163 //#define HAS_ALTIVEC // CFLAGS += -maltivec 164 //#define IS_PPC405 165 /**********************************************************************/ 166 167 168 #include <stdint.h> 169 #include "tests/sys_mman.h" 170 #include "tests/malloc.h" // memalign16 171 172 #define STATIC_ASSERT(e) sizeof(struct { int:-!(e); }) 173 174 /* Something of the same size as void*, so can be safely be coerced 175 * to/from a pointer type. Also same size as the host's gp registers. 176 * According to the AltiVec section of the GCC manual, the syntax does 177 * not allow the use of a typedef name as a type specifier in conjunction 178 * with the vector keyword, so typedefs uint[32|64]_t are #undef'ed here 179 * and redefined using #define. 180 */ 181 #undef uint32_t 182 #undef uint64_t 183 #define uint32_t unsigned int 184 #define uint64_t unsigned long long int 185 186 #ifndef __powerpc64__ 187 typedef uint32_t HWord_t; 188 #else 189 typedef uint64_t HWord_t; 190 #endif /* __powerpc64__ */ 191 192 enum { 193 compile_time_test1 = STATIC_ASSERT(sizeof(uint32_t) == 4), 194 compile_time_test2 = STATIC_ASSERT(sizeof(uint64_t) == 8), 195 }; 196 197 #define ALLCR "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7" 198 199 #define SET_CR(_arg) \ 200 __asm__ __volatile__ ("mtcr %0" : : "b"(_arg) : ALLCR ); 201 202 #define SET_XER(_arg) \ 203 __asm__ __volatile__ ("mtxer %0" : : "b"(_arg) : "xer" ); 204 205 #define GET_CR(_lval) \ 206 __asm__ __volatile__ ("mfcr %0" : "=b"(_lval) ) 207 208 #define GET_XER(_lval) \ 209 __asm__ __volatile__ ("mfxer %0" : "=b"(_lval) ) 210 211 #define GET_CR_XER(_lval_cr,_lval_xer) \ 212 do { GET_CR(_lval_cr); GET_XER(_lval_xer); } while (0) 213 214 #define SET_CR_ZERO \ 215 SET_CR(0) 216 217 #define SET_XER_ZERO \ 218 SET_XER(0) 219 220 #define SET_CR_XER_ZERO \ 221 do { SET_CR_ZERO; SET_XER_ZERO; } while (0) 222 223 #define SET_FPSCR_ZERO \ 224 do { double _d = 0.0; \ 225 __asm__ __volatile__ ("mtfsf 0xFF, %0" : : "f"(_d) ); \ 226 } while (0) 227 228 229 /* XXXX these must all be callee-save regs! */ 230 register double f14 __asm__ ("fr14"); 231 register double f15 __asm__ ("fr15"); 232 register double f16 __asm__ ("fr16"); 233 register double f17 __asm__ ("fr17"); 234 register HWord_t r14 __asm__ ("r14"); 235 register HWord_t r15 __asm__ ("r15"); 236 register HWord_t r16 __asm__ ("r16"); 237 register HWord_t r17 __asm__ ("r17"); 238 239 #include "config.h" // HAS_ALTIVEC 240 #if defined (HAS_ALTIVEC) 241 # include <altivec.h> 242 #endif 243 #include <assert.h> 244 #include <ctype.h> // isspace 245 #include <stdio.h> 246 #include <stdlib.h> 247 #include <string.h> 248 #include <unistd.h> // getopt 249 250 251 #ifndef __powerpc64__ 252 #define ASSEMBLY_FUNC(__fname, __insn) \ 253 asm(".section \".text\"\n" \ 254 "\t.align 2\n" \ 255 "\t.type "__fname",@function\n" \ 256 __fname":\n" \ 257 "\t"__insn"\n" \ 258 "\tblr\n" \ 259 "\t.previous\n" \ 260 ) 261 #else 262 #define ASSEMBLY_FUNC(__fname, __insn) \ 263 asm(".section \".text\"\n" \ 264 "\t.align 2\n" \ 265 "\t.global "__fname"\n" \ 266 "\t.section \".opd\",\"aw\"\n" \ 267 "\t.align 3\n" \ 268 ""__fname":\n" \ 269 "\t.quad ."__fname",.TOC.@tocbase,0\n" \ 270 "\t.previous\n" \ 271 "\t.type ."__fname",@function\n" \ 272 "\t.global ."__fname"\n" \ 273 "."__fname":\n" \ 274 "\t"__insn"\n" \ 275 "\tblr\n" \ 276 ) 277 #endif // #ifndef __powerpc64__ 278 279 280 /* Return a pointer to a 1-page area where is is safe to both write 281 and execute instructions. Area is filled with 'trap' insns. */ 282 static 283 uint32_t* get_rwx_area ( void ) 284 { 285 int i; 286 static uint32_t* p = NULL; 287 if (p == NULL) { 288 p = mmap(NULL, 4096, PROT_READ|PROT_WRITE|PROT_EXEC, 289 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 290 assert(p != MAP_FAILED); 291 } 292 293 for (i = 0; i < 4096/sizeof(uint32_t); i++) 294 p[i] = 0x7fe00008; /* trap */ 295 296 return p; 297 } 298 299 300 /* -------------- BEGIN #include "test-ppc.h" -------------- */ 301 /* 302 * test-ppc.h: 303 * PPC tests for qemu-PPC CPU emulation checks - definitions 304 * 305 * Copyright (c) 2005 Jocelyn Mayer 306 * 307 * This program is free software; you can redistribute it and/or 308 * modify it under the terms of the GNU General Public License V2 309 * as published by the Free Software Foundation 310 * 311 * This program is distributed in the hope that it will be useful, 312 * but WITHOUT ANY WARRANTY; without even the implied warranty of 313 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 314 * GNU General Public License for more details. 315 * 316 * You should have received a copy of the GNU General Public License 317 * along with this program; if not, write to the Free Software 318 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 319 */ 320 321 #if !defined (__TEST_PPC_H__) 322 #define __TEST_PPC_H__ 323 324 #include <stdint.h> 325 326 typedef void (*test_func_t) (void); 327 typedef struct test_t test_t; 328 typedef struct test_table_t test_table_t; 329 struct test_t { 330 test_func_t func; 331 const char *name; 332 }; 333 334 struct test_table_t { 335 test_t *tests; 336 const char *name; 337 uint32_t flags; 338 }; 339 340 typedef void (*test_loop_t) (const char *name, test_func_t func, 341 uint32_t flags); 342 343 enum test_flags { 344 /* Nb arguments */ 345 PPC_ONE_ARG = 0x00000001, 346 PPC_TWO_ARGS = 0x00000002, 347 PPC_THREE_ARGS = 0x00000003, 348 PPC_CMP_ARGS = 0x00000004, // family: compare 349 PPC_CMPI_ARGS = 0x00000005, // family: compare 350 PPC_TWO_I16 = 0x00000006, // family: arith/logical 351 PPC_SPECIAL = 0x00000007, // family: logical 352 PPC_LD_ARGS = 0x00000008, // family: ldst 353 PPC_LDX_ARGS = 0x00000009, // family: ldst 354 PPC_ST_ARGS = 0x0000000A, // family: ldst 355 PPC_STX_ARGS = 0x0000000B, // family: ldst 356 PPC_NB_ARGS = 0x0000000F, 357 /* Type */ 358 PPC_ARITH = 0x00000100, 359 PPC_LOGICAL = 0x00000200, 360 PPC_COMPARE = 0x00000300, 361 PPC_CROP = 0x00000400, 362 PPC_LDST = 0x00000500, 363 PPC_POPCNT = 0x00000600, 364 PPC_TYPE = 0x00000F00, 365 /* Family */ 366 PPC_INTEGER = 0x00010000, 367 PPC_FLOAT = 0x00020000, 368 PPC_405 = 0x00030000, 369 PPC_ALTIVEC = 0x00040000, 370 PPC_FALTIVEC = 0x00050000, 371 PPC_FAMILY = 0x000F0000, 372 /* Flags: these may be combined, so use separate bitfields. */ 373 PPC_CR = 0x01000000, 374 PPC_XER_CA = 0x02000000, 375 }; 376 377 #endif /* !defined (__TEST_PPC_H__) */ 378 379 /* -------------- END #include "test-ppc.h" -------------- */ 380 381 382 383 384 #if defined (DEBUG_ARGS_BUILD) 385 #define AB_DPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0) 386 #else 387 #define AB_DPRINTF(fmt, args...) do { } while (0) 388 #endif 389 390 #if defined (DEBUG_FILTER) 391 #define FDPRINTF(fmt, args...) do { fprintf(stderr, fmt , ##args); } while (0) 392 #else 393 #define FDPRINTF(fmt, args...) do { } while (0) 394 #endif 395 396 397 /* Produce the 64-bit pattern corresponding to the supplied double. */ 398 static uint64_t double_to_bits ( double d ) 399 { 400 union { uint64_t i; double d; } u; 401 assert(8 == sizeof(uint64_t)); 402 assert(8 == sizeof(double)); 403 assert(8 == sizeof(u)); 404 u.d = d; 405 return u.i; 406 } 407 408 #if 0 409 static float bits_to_float ( uint32_t i ) 410 { 411 union { uint32_t i; float f; } u; 412 assert(4 == sizeof(uint32_t)); 413 assert(4 == sizeof(float)); 414 assert(4 == sizeof(u)); 415 u.i = i; 416 return u.f; 417 } 418 #endif 419 420 421 #if defined (HAS_ALTIVEC) 422 static void AB_DPRINTF_VEC32x4 ( vector unsigned int v ) 423 { 424 #if defined (DEBUG_ARGS_BUILD) 425 int i; 426 unsigned int* p_int = (unsigned int*)&v; 427 AB_DPRINTF("val"); 428 for (i=0; i<4; i++) { 429 AB_DPRINTF(" %08x", p_int[i]); 430 } 431 AB_DPRINTF("\n"); 432 #endif 433 } 434 #endif 435 436 437 #define unused __attribute__ (( unused )) 438 439 440 /* -------------- BEGIN #include "ops-ppc.c" -------------- */ 441 442 /* #include "test-ppc.h" */ 443 444 static void test_add (void) 445 { 446 __asm__ __volatile__ ("add 17, 14, 15"); 447 } 448 449 static void test_addo (void) 450 { 451 __asm__ __volatile__ ("addo 17, 14, 15"); 452 } 453 454 static void test_addc (void) 455 { 456 __asm__ __volatile__ ("addc 17, 14, 15"); 457 } 458 459 static void test_addco (void) 460 { 461 __asm__ __volatile__ ("addco 17, 14, 15"); 462 } 463 464 static void test_divw (void) 465 { 466 __asm__ __volatile__ ("divw 17, 14, 15"); 467 } 468 469 static void test_divwo (void) 470 { 471 __asm__ __volatile__ ("divwo 17, 14, 15"); 472 } 473 474 static void test_divwu (void) 475 { 476 __asm__ __volatile__ ("divwu 17, 14, 15"); 477 } 478 479 static void test_divwuo (void) 480 { 481 __asm__ __volatile__ ("divwuo 17, 14, 15"); 482 } 483 484 static void test_mulhw (void) 485 { 486 __asm__ __volatile__ ("mulhw 17, 14, 15"); 487 } 488 489 static void test_mulhwu (void) 490 { 491 __asm__ __volatile__ ("mulhwu 17, 14, 15"); 492 } 493 494 static void test_mullw (void) 495 { 496 __asm__ __volatile__ ("mullw 17, 14, 15"); 497 } 498 499 static void test_mullwo (void) 500 { 501 __asm__ __volatile__ ("mullwo 17, 14, 15"); 502 } 503 504 static void test_subf (void) 505 { 506 __asm__ __volatile__ ("subf 17, 14, 15"); 507 } 508 509 static void test_subfo (void) 510 { 511 __asm__ __volatile__ ("subfo 17, 14, 15"); 512 } 513 514 static void test_subfc (void) 515 { 516 __asm__ __volatile__ ("subfc 17, 14, 15"); 517 } 518 519 static void test_subfco (void) 520 { 521 __asm__ __volatile__ ("subfco 17, 14, 15"); 522 } 523 524 #ifdef __powerpc64__ 525 static void test_mulld (void) 526 { 527 __asm__ __volatile__ ("mulld 17, 14, 15"); 528 } 529 530 static void test_mulhd (void) 531 { 532 __asm__ __volatile__ ("mulhd 17, 14, 15"); 533 } 534 535 static void test_mulhdu (void) 536 { 537 __asm__ __volatile__ ("mulhdu 17, 14, 15"); 538 } 539 540 static void test_divd (void) 541 { 542 __asm__ __volatile__ ("divd 17, 14, 15"); 543 } 544 545 static void test_divdu (void) 546 { 547 __asm__ __volatile__ ("divdu 17, 14, 15"); 548 } 549 #endif // #ifdef __powerpc64__ 550 551 static test_t tests_ia_ops_two[] = { 552 { &test_add , " add", }, 553 { &test_addo , " addo", }, 554 { &test_addc , " addc", }, 555 { &test_addco , " addco", }, 556 { &test_divw , " divw", }, 557 { &test_divwo , " divwo", }, 558 { &test_divwu , " divwu", }, 559 { &test_divwuo , " divwuo", }, 560 { &test_mulhw , " mulhw", }, 561 { &test_mulhwu , " mulhwu", }, 562 { &test_mullw , " mullw", }, 563 { &test_mullwo , " mullwo", }, 564 { &test_subf , " subf", }, 565 { &test_subfo , " subfo", }, 566 { &test_subfc , " subfc", }, 567 { &test_subfco , " subfco", }, 568 #ifdef __powerpc64__ 569 { &test_mulhd , " mulhd", }, 570 { &test_mulhdu , " mulhdu", }, 571 { &test_mulld , " mulld", }, 572 { &test_divd , " divd", }, 573 { &test_divdu , " divdu", }, 574 #endif // #ifdef __powerpc64__ 575 { NULL, NULL, }, 576 }; 577 578 static void test_add_ (void) 579 { 580 __asm__ __volatile__ ("add. 17, 14, 15"); 581 } 582 583 static void test_addo_ (void) 584 { 585 __asm__ __volatile__ ("addo. 17, 14, 15"); 586 } 587 588 static void test_addc_ (void) 589 { 590 __asm__ __volatile__ ("addc. 17, 14, 15"); 591 } 592 593 static void test_addco_ (void) 594 { 595 __asm__ __volatile__ ("addco. 17, 14, 15"); 596 } 597 598 static void test_divw_ (void) 599 { 600 __asm__ __volatile__ ("divw. 17, 14, 15"); 601 } 602 603 static void test_divwo_ (void) 604 { 605 __asm__ __volatile__ ("divwo. 17, 14, 15"); 606 } 607 608 static void test_divwu_ (void) 609 { 610 __asm__ __volatile__ ("divwu. 17, 14, 15"); 611 } 612 613 static void test_divwuo_ (void) 614 { 615 __asm__ __volatile__ ("divwuo. 17, 14, 15"); 616 } 617 618 static void test_mulhw_ (void) 619 { 620 __asm__ __volatile__ ("mulhw. 17, 14, 15"); 621 } 622 623 static void test_mulhwu_ (void) 624 { 625 __asm__ __volatile__ ("mulhwu. 17, 14, 15"); 626 } 627 628 static void test_mullw_ (void) 629 { 630 __asm__ __volatile__ ("mullw. 17, 14, 15"); 631 } 632 633 static void test_mullwo_ (void) 634 { 635 __asm__ __volatile__ ("mullwo. 17, 14, 15"); 636 } 637 638 static void test_subf_ (void) 639 { 640 __asm__ __volatile__ ("subf. 17, 14, 15"); 641 } 642 643 static void test_subfo_ (void) 644 { 645 __asm__ __volatile__ ("subfo. 17, 14, 15"); 646 } 647 648 static void test_subfc_ (void) 649 { 650 __asm__ __volatile__ ("subfc. 17, 14, 15"); 651 } 652 653 static void test_subfco_ (void) 654 { 655 __asm__ __volatile__ ("subfco. 17, 14, 15"); 656 } 657 658 #ifdef __powerpc64__ 659 static void test_mulhd_ (void) 660 { 661 __asm__ __volatile__ ("mulhd. 17, 14, 15"); 662 } 663 664 static void test_mulhdu_ (void) 665 { 666 __asm__ __volatile__ ("mulhdu. 17, 14, 15"); 667 } 668 669 static void test_mulld_ (void) 670 { 671 __asm__ __volatile__ ("mulld. 17, 14, 15"); 672 } 673 674 static void test_divd_ (void) 675 { 676 __asm__ __volatile__ ("divd. 17, 14, 15"); 677 } 678 679 static void test_divdu_ (void) 680 { 681 __asm__ __volatile__ ("divdu. 17, 14, 15"); 682 } 683 #endif // #ifdef __powerpc64__ 684 685 static test_t tests_iar_ops_two[] = { 686 { &test_add_ , " add.", }, 687 { &test_addo_ , " addo.", }, 688 { &test_addc_ , " addc.", }, 689 { &test_addco_ , " addco.", }, 690 { &test_divw_ , " divw.", }, 691 { &test_divwo_ , " divwo.", }, 692 { &test_divwu_ , " divwu.", }, 693 { &test_divwuo_ , " divwuo.", }, 694 { &test_mulhw_ , " mulhw.", }, 695 { &test_mulhwu_ , " mulhwu.", }, 696 { &test_mullw_ , " mullw.", }, 697 { &test_mullwo_ , " mullwo.", }, 698 { &test_subf_ , " subf.", }, 699 { &test_subfo_ , " subfo.", }, 700 { &test_subfc_ , " subfc.", }, 701 { &test_subfco_ , " subfco.", }, 702 #ifdef __powerpc64__ 703 { &test_mulhd_ , " mulhd.", }, 704 { &test_mulhdu_ , " mulhdu.", }, 705 { &test_mulld_ , " mulld.", }, 706 { &test_divd_ , " divd.", }, 707 { &test_divdu_ , " divdu.", }, 708 #endif // #ifdef __powerpc64__ 709 { NULL, NULL, }, 710 }; 711 712 static void test_adde (void) 713 { 714 __asm__ __volatile__ ("adde 17, 14, 15"); 715 } 716 717 static void test_addeo (void) 718 { 719 __asm__ __volatile__ ("addeo 17, 14, 15"); 720 } 721 722 static void test_subfe (void) 723 { 724 __asm__ __volatile__ ("subfe 17, 14, 15"); 725 } 726 727 static void test_subfeo (void) 728 { 729 __asm__ __volatile__ ("subfeo 17, 14, 15"); 730 } 731 732 static test_t tests_iac_ops_two[] = { 733 { &test_adde , " adde", }, 734 { &test_addeo , " addeo", }, 735 { &test_subfe , " subfe", }, 736 { &test_subfeo , " subfeo", }, 737 { NULL, NULL, }, 738 }; 739 740 static void test_adde_ (void) 741 { 742 __asm__ __volatile__ ("adde. 17, 14, 15"); 743 } 744 745 static void test_addeo_ (void) 746 { 747 __asm__ __volatile__ ("addeo. 17, 14, 15"); 748 } 749 750 static void test_subfe_ (void) 751 { 752 __asm__ __volatile__ ("subfe. 17, 14, 15"); 753 } 754 755 static void test_subfeo_ (void) 756 { 757 __asm__ __volatile__ ("subfeo. 17, 14, 15"); 758 } 759 760 static test_t tests_iacr_ops_two[] = { 761 { &test_adde_ , " adde.", }, 762 { &test_addeo_ , " addeo.", }, 763 { &test_subfe_ , " subfe.", }, 764 { &test_subfeo_ , " subfeo.", }, 765 { NULL, NULL, }, 766 }; 767 768 static void test_and (void) 769 { 770 __asm__ __volatile__ ("and 17, 14, 15"); 771 } 772 773 static void test_andc (void) 774 { 775 __asm__ __volatile__ ("andc 17, 14, 15"); 776 } 777 778 static void test_eqv (void) 779 { 780 __asm__ __volatile__ ("eqv 17, 14, 15"); 781 } 782 783 static void test_nand (void) 784 { 785 __asm__ __volatile__ ("nand 17, 14, 15"); 786 } 787 788 static void test_nor (void) 789 { 790 __asm__ __volatile__ ("nor 17, 14, 15"); 791 } 792 793 static void test_or (void) 794 { 795 __asm__ __volatile__ ("or 17, 14, 15"); 796 } 797 798 static void test_orc (void) 799 { 800 __asm__ __volatile__ ("orc 17, 14, 15"); 801 } 802 803 static void test_xor (void) 804 { 805 __asm__ __volatile__ ("xor 17, 14, 15"); 806 } 807 808 static void test_slw (void) 809 { 810 __asm__ __volatile__ ("slw 17, 14, 15"); 811 } 812 813 static void test_sraw (void) 814 { 815 __asm__ __volatile__ ("sraw 17, 14, 15"); 816 } 817 818 static void test_srw (void) 819 { 820 __asm__ __volatile__ ("srw 17, 14, 15"); 821 } 822 823 #ifdef __powerpc64__ 824 static void test_sld (void) 825 { 826 __asm__ __volatile__ ("sld 17, 14, 15"); 827 } 828 829 static void test_srad (void) 830 { 831 __asm__ __volatile__ ("srad 17, 14, 15"); 832 } 833 834 static void test_srd (void) 835 { 836 __asm__ __volatile__ ("srd 17, 14, 15"); 837 } 838 #endif // #ifdef __powerpc64__ 839 840 static test_t tests_il_ops_two[] = { 841 { &test_and , " and", }, 842 { &test_andc , " andc", }, 843 { &test_eqv , " eqv", }, 844 { &test_nand , " nand", }, 845 { &test_nor , " nor", }, 846 { &test_or , " or", }, 847 { &test_orc , " orc", }, 848 { &test_xor , " xor", }, 849 { &test_slw , " slw", }, 850 { &test_sraw , " sraw", }, 851 { &test_srw , " srw", }, 852 #ifdef __powerpc64__ 853 { &test_sld , " sld", }, 854 { &test_srad , " srad", }, 855 { &test_srd , " srd", }, 856 #endif // #ifdef __powerpc64__ 857 { NULL, NULL, }, 858 }; 859 860 static void test_and_ (void) 861 { 862 __asm__ __volatile__ ("and. 17, 14, 15"); 863 } 864 865 static void test_andc_ (void) 866 { 867 __asm__ __volatile__ ("andc. 17, 14, 15"); 868 } 869 870 static void test_eqv_ (void) 871 { 872 __asm__ __volatile__ ("eqv. 17, 14, 15"); 873 } 874 875 static void test_nand_ (void) 876 { 877 __asm__ __volatile__ ("nand. 17, 14, 15"); 878 } 879 880 static void test_nor_ (void) 881 { 882 __asm__ __volatile__ ("nor. 17, 14, 15"); 883 } 884 885 static void test_or_ (void) 886 { 887 __asm__ __volatile__ ("or. 17, 14, 15"); 888 } 889 890 static void test_orc_ (void) 891 { 892 __asm__ __volatile__ ("orc. 17, 14, 15"); 893 } 894 895 static void test_xor_ (void) 896 { 897 __asm__ __volatile__ ("xor. 17, 14, 15"); 898 } 899 900 static void test_slw_ (void) 901 { 902 __asm__ __volatile__ ("slw. 17, 14, 15"); 903 } 904 905 static void test_sraw_ (void) 906 { 907 __asm__ __volatile__ ("sraw. 17, 14, 15"); 908 } 909 910 static void test_srw_ (void) 911 { 912 __asm__ __volatile__ ("srw. 17, 14, 15"); 913 } 914 915 #ifdef __powerpc64__ 916 static void test_sld_ (void) 917 { 918 __asm__ __volatile__ ("sld. 17, 14, 15"); 919 } 920 921 static void test_srad_ (void) 922 { 923 __asm__ __volatile__ ("srad. 17, 14, 15"); 924 } 925 926 static void test_srd_ (void) 927 { 928 __asm__ __volatile__ ("srd. 17, 14, 15"); 929 } 930 #endif // #ifdef __powerpc64__ 931 932 static test_t tests_ilr_ops_two[] = { 933 { &test_and_ , " and.", }, 934 { &test_andc_ , " andc.", }, 935 { &test_eqv_ , " eqv.", }, 936 { &test_nand_ , " nand.", }, 937 { &test_nor_ , " nor.", }, 938 { &test_or_ , " or.", }, 939 { &test_orc_ , " orc.", }, 940 { &test_xor_ , " xor.", }, 941 { &test_slw_ , " slw.", }, 942 { &test_sraw_ , " sraw.", }, 943 { &test_srw_ , " srw.", }, 944 #ifdef __powerpc64__ 945 { &test_sld_ , " sld.", }, 946 { &test_srad_ , " srad.", }, 947 { &test_srd_ , " srd.", }, 948 #endif // #ifdef __powerpc64__ 949 { NULL, NULL, }, 950 }; 951 952 static void test_cmpw (void) 953 { 954 __asm__ __volatile__ ("cmpw 2, 14, 15"); 955 } 956 957 static void test_cmplw (void) 958 { 959 __asm__ __volatile__ ("cmplw 2, 14, 15"); 960 } 961 962 #ifdef __powerpc64__ 963 static void test_cmpd (void) 964 { 965 __asm__ __volatile__ ("cmpd 2, 14, 15"); 966 } 967 968 static void test_cmpld (void) 969 { 970 __asm__ __volatile__ ("cmpld 2, 14, 15"); 971 } 972 #endif // #ifdef __powerpc64__ 973 974 static test_t tests_icr_ops_two[] = { 975 { &test_cmpw , " cmpw", }, 976 { &test_cmplw , " cmplw", }, 977 #ifdef __powerpc64__ 978 { &test_cmpd , " cmpd", }, 979 { &test_cmpld , " cmpld", }, 980 #endif // #ifdef __powerpc64__ 981 { NULL, NULL, }, 982 }; 983 984 extern void test_cmpwi (void); 985 ASSEMBLY_FUNC("test_cmpwi", "cmpwi 2, 14, 0"); 986 987 extern void test_cmplwi (void); 988 ASSEMBLY_FUNC("test_cmplwi", "cmplwi 2, 14, 0"); 989 990 #ifdef __powerpc64__ 991 extern void test_cmpdi (void); 992 ASSEMBLY_FUNC("test_cmpdi", "cmpdi 2, 14, 0"); 993 994 extern void test_cmpldi (void); 995 ASSEMBLY_FUNC("test_cmpldi", "cmpldi 2, 14, 0"); 996 #endif // #ifdef __powerpc64__ 997 998 static test_t tests_icr_ops_two_i16[] = { 999 { &test_cmpwi , " cmpwi", }, 1000 { &test_cmplwi , " cmplwi", }, 1001 #ifdef __powerpc64__ 1002 { &test_cmpdi , " cmpdi", }, 1003 { &test_cmpldi , " cmpldi", }, 1004 #endif // #ifdef __powerpc64__ 1005 { NULL, NULL, }, 1006 }; 1007 1008 extern void test_addi (void); 1009 ASSEMBLY_FUNC("test_addi", "addi 17, 14, 0"); 1010 1011 extern void test_addic (void); 1012 ASSEMBLY_FUNC("test_addic", "addic 17, 14, 0"); 1013 1014 extern void test_addis (void); 1015 ASSEMBLY_FUNC("test_addis", "addis 17, 14, 0"); 1016 1017 extern void test_mulli (void); 1018 ASSEMBLY_FUNC("test_mulli", "mulli 17, 14, 0"); 1019 1020 extern void test_subfic (void); 1021 ASSEMBLY_FUNC("test_subfic", "subfic 17, 14, 0"); 1022 1023 static test_t tests_ia_ops_two_i16[] = { 1024 { &test_addi , " addi", }, 1025 { &test_addic , " addic", }, 1026 { &test_addis , " addis", }, 1027 { &test_mulli , " mulli", }, 1028 { &test_subfic , " subfic", }, 1029 { NULL, NULL, }, 1030 }; 1031 1032 extern void test_addic_ (void); 1033 ASSEMBLY_FUNC("test_addic_", "addic. 17, 14, 0"); 1034 1035 static test_t tests_iar_ops_two_i16[] = { 1036 { &test_addic_ , " addic.", }, 1037 { NULL, NULL, }, 1038 }; 1039 1040 extern void test_ori (void); 1041 ASSEMBLY_FUNC("test_ori", "ori 17, 14, 0"); 1042 1043 extern void test_oris (void); 1044 ASSEMBLY_FUNC("test_oris", "oris 17, 14, 0"); 1045 1046 extern void test_xori (void); 1047 ASSEMBLY_FUNC("test_xori", "xori 17, 14, 0"); 1048 1049 extern void test_xoris (void); 1050 ASSEMBLY_FUNC("test_xoris", "xoris 17, 14, 0"); 1051 1052 static test_t tests_il_ops_two_i16[] = { 1053 { &test_ori , " ori", }, 1054 { &test_oris , " oris", }, 1055 { &test_xori , " xori", }, 1056 { &test_xoris , " xoris", }, 1057 { NULL, NULL, }, 1058 }; 1059 1060 extern void test_andi_ (void); 1061 ASSEMBLY_FUNC("test_andi_", "andi. 17, 14, 0"); 1062 1063 extern void test_andis_ (void); 1064 ASSEMBLY_FUNC("test_andis_", "andis. 17, 14, 0"); 1065 1066 static test_t tests_ilr_ops_two_i16[] = { 1067 { &test_andi_ , " andi.", }, 1068 { &test_andis_ , " andis.", }, 1069 { NULL, NULL, }, 1070 }; 1071 1072 static void test_crand (void) 1073 { 1074 __asm__ __volatile__ ("crand 17, 14, 15"); 1075 } 1076 1077 static void test_crandc (void) 1078 { 1079 __asm__ __volatile__ ("crandc 17, 14, 15"); 1080 } 1081 1082 static void test_creqv (void) 1083 { 1084 __asm__ __volatile__ ("creqv 17, 14, 15"); 1085 } 1086 1087 static void test_crnand (void) 1088 { 1089 __asm__ __volatile__ ("crnand 17, 14, 15"); 1090 } 1091 1092 static void test_crnor (void) 1093 { 1094 __asm__ __volatile__ ("crnor 17, 14, 15"); 1095 } 1096 1097 static void test_cror (void) 1098 { 1099 __asm__ __volatile__ ("cror 17, 14, 15"); 1100 } 1101 1102 static void test_crorc (void) 1103 { 1104 __asm__ __volatile__ ("crorc 17, 14, 15"); 1105 } 1106 1107 static void test_crxor (void) 1108 { 1109 __asm__ __volatile__ ("crxor 17, 14, 15"); 1110 } 1111 1112 static test_t tests_crl_ops_two[] = { 1113 { &test_crand , " crand", }, 1114 { &test_crandc , " crandc", }, 1115 { &test_creqv , " creqv", }, 1116 { &test_crnand , " crnand", }, 1117 { &test_crnor , " crnor", }, 1118 { &test_cror , " cror", }, 1119 { &test_crorc , " crorc", }, 1120 { &test_crxor , " crxor", }, 1121 { NULL, NULL, }, 1122 }; 1123 1124 static void test_addme (void) 1125 { 1126 __asm__ __volatile__ ("addme 17, 14"); 1127 } 1128 1129 static void test_addmeo (void) 1130 { 1131 __asm__ __volatile__ ("addmeo 17, 14"); 1132 } 1133 1134 static void test_addze (void) 1135 { 1136 __asm__ __volatile__ ("addze 17, 14"); 1137 } 1138 1139 static void test_addzeo (void) 1140 { 1141 __asm__ __volatile__ ("addzeo 17, 14"); 1142 } 1143 1144 static void test_subfme (void) 1145 { 1146 __asm__ __volatile__ ("subfme 17, 14"); 1147 } 1148 1149 static void test_subfmeo (void) 1150 { 1151 __asm__ __volatile__ ("subfmeo 17, 14"); 1152 } 1153 1154 static void test_subfze (void) 1155 { 1156 __asm__ __volatile__ ("subfze 17, 14"); 1157 } 1158 1159 static void test_subfzeo (void) 1160 { 1161 __asm__ __volatile__ ("subfzeo 17, 14"); 1162 } 1163 1164 static test_t tests_iac_ops_one[] = { 1165 { &test_addme , " addme", }, 1166 { &test_addmeo , " addmeo", }, 1167 { &test_addze , " addze", }, 1168 { &test_addzeo , " addzeo", }, 1169 { &test_subfme , " subfme", }, 1170 { &test_subfmeo , " subfmeo", }, 1171 { &test_subfze , " subfze", }, 1172 { &test_subfzeo , " subfzeo", }, 1173 { NULL, NULL, }, 1174 }; 1175 1176 static void test_addme_ (void) 1177 { 1178 __asm__ __volatile__ ("addme. 17, 14"); 1179 } 1180 1181 static void test_addmeo_ (void) 1182 { 1183 __asm__ __volatile__ ("addmeo. 17, 14"); 1184 } 1185 1186 static void test_addze_ (void) 1187 { 1188 __asm__ __volatile__ ("addze. 17, 14"); 1189 } 1190 1191 static void test_addzeo_ (void) 1192 { 1193 __asm__ __volatile__ ("addzeo. 17, 14"); 1194 } 1195 1196 static void test_subfme_ (void) 1197 { 1198 __asm__ __volatile__ ("subfme. 17, 14"); 1199 } 1200 1201 static void test_subfmeo_ (void) 1202 { 1203 __asm__ __volatile__ ("subfmeo. 17, 14"); 1204 } 1205 1206 static void test_subfze_ (void) 1207 { 1208 __asm__ __volatile__ ("subfze. 17, 14"); 1209 } 1210 1211 static void test_subfzeo_ (void) 1212 { 1213 __asm__ __volatile__ ("subfzeo. 17, 14"); 1214 } 1215 1216 static test_t tests_iacr_ops_one[] = { 1217 { &test_addme_ , " addme.", }, 1218 { &test_addmeo_ , " addmeo.", }, 1219 { &test_addze_ , " addze.", }, 1220 { &test_addzeo_ , " addzeo.", }, 1221 { &test_subfme_ , " subfme.", }, 1222 { &test_subfmeo_ , " subfmeo.", }, 1223 { &test_subfze_ , " subfze.", }, 1224 { &test_subfzeo_ , " subfzeo.", }, 1225 { NULL, NULL, }, 1226 }; 1227 1228 static void test_cntlzw (void) 1229 { 1230 __asm__ __volatile__ ("cntlzw 17, 14"); 1231 } 1232 1233 static void test_extsb (void) 1234 { 1235 __asm__ __volatile__ ("extsb 17, 14"); 1236 } 1237 1238 static void test_extsh (void) 1239 { 1240 __asm__ __volatile__ ("extsh 17, 14"); 1241 } 1242 1243 static void test_neg (void) 1244 { 1245 __asm__ __volatile__ ("neg 17, 14"); 1246 } 1247 1248 static void test_nego (void) 1249 { 1250 __asm__ __volatile__ ("nego 17, 14"); 1251 } 1252 1253 #ifdef __powerpc64__ 1254 static void test_cntlzd (void) 1255 { 1256 __asm__ __volatile__ ("cntlzd 17, 14"); 1257 } 1258 1259 static void test_extsw (void) 1260 { 1261 __asm__ __volatile__ ("extsw 17, 14"); 1262 } 1263 #endif // #ifdef __powerpc64__ 1264 1265 static test_t tests_il_ops_one[] = { 1266 { &test_cntlzw , " cntlzw", }, 1267 { &test_extsb , " extsb", }, 1268 { &test_extsh , " extsh", }, 1269 { &test_neg , " neg", }, 1270 { &test_nego , " nego", }, 1271 #ifdef __powerpc64__ 1272 { &test_cntlzd , " cntlzd", }, 1273 { &test_extsw , " extsw", }, 1274 #endif // #ifdef __powerpc64__ 1275 { NULL, NULL, }, 1276 }; 1277 1278 static void test_cntlzw_ (void) 1279 { 1280 __asm__ __volatile__ ("cntlzw. 17, 14"); 1281 } 1282 1283 static void test_extsb_ (void) 1284 { 1285 __asm__ __volatile__ ("extsb. 17, 14"); 1286 } 1287 1288 static void test_extsh_ (void) 1289 { 1290 __asm__ __volatile__ ("extsh. 17, 14"); 1291 } 1292 1293 static void test_neg_ (void) 1294 { 1295 __asm__ __volatile__ ("neg. 17, 14"); 1296 } 1297 1298 static void test_nego_ (void) 1299 { 1300 __asm__ __volatile__ ("nego. 17, 14"); 1301 } 1302 1303 #ifdef __powerpc64__ 1304 static void test_cntlzd_ (void) 1305 { 1306 __asm__ __volatile__ ("cntlzd. 17, 14"); 1307 } 1308 1309 static void test_extsw_ (void) 1310 { 1311 __asm__ __volatile__ ("extsw. 17, 14"); 1312 } 1313 #endif // #ifdef __powerpc64__ 1314 1315 static test_t tests_ilr_ops_one[] = { 1316 { &test_cntlzw_ , " cntlzw.", }, 1317 { &test_extsb_ , " extsb.", }, 1318 { &test_extsh_ , " extsh.", }, 1319 { &test_neg_ , " neg.", }, 1320 { &test_nego_ , " nego.", }, 1321 #ifdef __powerpc64__ 1322 { &test_cntlzd_ , " cntlzd.", }, 1323 { &test_extsw_ , " extsw.", }, 1324 #endif // #ifdef __powerpc64__ 1325 { NULL, NULL, }, 1326 }; 1327 1328 extern void test_rlwimi (void); 1329 ASSEMBLY_FUNC("test_rlwimi", "rlwimi 17, 14, 0, 0, 0"); 1330 1331 extern void test_rlwinm (void); 1332 ASSEMBLY_FUNC("test_rlwinm", "rlwinm 17, 14, 0, 0, 0"); 1333 1334 extern void test_rlwnm (void); 1335 ASSEMBLY_FUNC("test_rlwnm", "rlwnm 17, 14, 15, 0, 0"); 1336 1337 extern void test_srawi (void); 1338 ASSEMBLY_FUNC("test_srawi", "srawi 17, 14, 0"); 1339 1340 static void test_mfcr (void) 1341 { 1342 __asm__ __volatile__ ("mfcr 17"); 1343 } 1344 1345 static void test_mfspr (void) 1346 { 1347 __asm__ __volatile__ ("mfspr 17, 1"); 1348 } 1349 1350 static void test_mtspr (void) 1351 { 1352 __asm__ __volatile__ ("mtspr 1, 14"); 1353 } 1354 1355 #ifdef __powerpc64__ 1356 extern void test_rldcl (void); 1357 ASSEMBLY_FUNC("test_rldcl", "rldcl 17, 14, 15, 0"); 1358 1359 extern void test_rldcr (void); 1360 ASSEMBLY_FUNC("test_rldcr", "rldcr 17, 14, 15, 0"); 1361 1362 extern void test_rldic (void); 1363 ASSEMBLY_FUNC("test_rldic", "rldic 17, 14, 0, 0"); 1364 1365 extern void test_rldicl (void); 1366 ASSEMBLY_FUNC("test_rldicl", "rldicl 17, 14, 0, 0"); 1367 1368 extern void test_rldicr (void); 1369 ASSEMBLY_FUNC("test_rldicr", "rldicr 17, 14, 0, 0"); 1370 1371 extern void test_rldimi (void); 1372 ASSEMBLY_FUNC("test_rldimi", "rldimi 17, 14, 0, 0"); 1373 1374 extern void test_sradi (void); 1375 ASSEMBLY_FUNC("test_sradi", "sradi 17, 14, 0"); 1376 #endif // #ifdef __powerpc64__ 1377 1378 static test_t tests_il_ops_spe[] = { 1379 { &test_rlwimi , " rlwimi", }, 1380 { &test_rlwinm , " rlwinm", }, 1381 { &test_rlwnm , " rlwnm", }, 1382 { &test_srawi , " srawi", }, 1383 { &test_mfcr , " mfcr", }, 1384 { &test_mfspr , " mfspr", }, 1385 { &test_mtspr , " mtspr", }, 1386 #ifdef __powerpc64__ 1387 { &test_rldcl , " rldcl", }, 1388 { &test_rldcr , " rldcr", }, 1389 { &test_rldic , " rldic", }, 1390 { &test_rldicl , " rldicl", }, 1391 { &test_rldicr , " rldicr", }, 1392 { &test_rldimi , " rldimi", }, 1393 { &test_sradi , " sradi", }, 1394 #endif // #ifdef __powerpc64__ 1395 { NULL, NULL, }, 1396 }; 1397 1398 extern void test_rlwimi_ (void); 1399 ASSEMBLY_FUNC("test_rlwimi_", "rlwimi. 17, 14, 0, 0, 0"); 1400 1401 extern void test_rlwinm_ (void); 1402 ASSEMBLY_FUNC("test_rlwinm_", "rlwinm. 17, 14, 0, 0, 0"); 1403 1404 extern void test_rlwnm_ (void); 1405 ASSEMBLY_FUNC("test_rlwnm_", "rlwnm. 17, 14, 15, 0, 0"); 1406 1407 extern void test_srawi_ (void); 1408 ASSEMBLY_FUNC("test_srawi_", "srawi. 17, 14, 0"); 1409 1410 extern void test_mcrf (void); 1411 ASSEMBLY_FUNC("test_mcrf", "mcrf 0, 0"); 1412 1413 extern void test_mcrxr (void); 1414 ASSEMBLY_FUNC("test_mcrxr", "mcrxr 0"); 1415 1416 extern void test_mtcrf (void); 1417 ASSEMBLY_FUNC("test_mtcrf", "mtcrf 0, 14"); 1418 1419 #ifdef __powerpc64__ 1420 extern void test_rldcl_ (void); 1421 ASSEMBLY_FUNC("test_rldcl_", "rldcl. 17, 14, 15, 0"); 1422 1423 extern void test_rldcr_ (void); 1424 ASSEMBLY_FUNC("test_rldcr_", "rldcr. 17, 14, 15, 0"); 1425 1426 extern void test_rldic_ (void); 1427 ASSEMBLY_FUNC("test_rldic_", "rldic. 17, 14, 0, 0"); 1428 1429 extern void test_rldicl_ (void); 1430 ASSEMBLY_FUNC("test_rldicl_", "rldicl. 17, 14, 0, 0"); 1431 1432 extern void test_rldicr_ (void); 1433 ASSEMBLY_FUNC("test_rldicr_", "rldicr. 17, 14, 0, 0"); 1434 1435 extern void test_rldimi_ (void); 1436 ASSEMBLY_FUNC("test_rldimi_", "rldimi. 17, 14, 0, 0"); 1437 1438 extern void test_sradi_ (void); 1439 ASSEMBLY_FUNC("test_sradi_", "sradi. 17, 14, 0"); 1440 #endif // #ifdef __powerpc64__ 1441 1442 static test_t tests_ilr_ops_spe[] = { 1443 { &test_rlwimi_ , " rlwimi.", }, 1444 { &test_rlwinm_ , " rlwinm.", }, 1445 { &test_rlwnm_ , " rlwnm.", }, 1446 { &test_srawi_ , " srawi.", }, 1447 { &test_mcrf , " mcrf", }, 1448 { &test_mcrxr , " mcrxr", }, 1449 { &test_mtcrf , " mtcrf", }, 1450 #ifdef __powerpc64__ 1451 { &test_rldcl_ , " rldcl.", }, 1452 { &test_rldcr_ , " rldcr.", }, 1453 { &test_rldic_ , " rldic.", }, 1454 { &test_rldicl_ , " rldicl.", }, 1455 { &test_rldicr_ , " rldicr.", }, 1456 { &test_rldimi_ , " rldimi.", }, 1457 { &test_sradi_ , " sradi.", }, 1458 #endif // #ifdef __powerpc64__ 1459 { NULL, NULL, }, 1460 }; 1461 1462 extern void test_lbz (void); 1463 ASSEMBLY_FUNC("test_lbz", "lbz 17,0(14)"); 1464 1465 extern void test_lbzu (void); 1466 ASSEMBLY_FUNC("test_lbzu", "lbzu 17,0(14)"); 1467 1468 extern void test_lha (void); 1469 ASSEMBLY_FUNC("test_lha", "lha 17,0(14)"); 1470 1471 extern void test_lhau (void); 1472 ASSEMBLY_FUNC("test_lhau", "lhau 17,0(14)"); 1473 1474 extern void test_lhz (void); 1475 ASSEMBLY_FUNC("test_lhz", "lhz 17,0(14)"); 1476 1477 extern void test_lhzu (void); 1478 ASSEMBLY_FUNC("test_lhzu", "lhzu 17,0(14)"); 1479 1480 extern void test_lwz (void); 1481 ASSEMBLY_FUNC("test_lwz", "lwz 17,0(14)"); 1482 1483 extern void test_lwzu (void); 1484 ASSEMBLY_FUNC("test_lwzu", "lwzu 17,0(14)"); 1485 1486 #ifdef __powerpc64__ 1487 extern void test_ld (void); 1488 ASSEMBLY_FUNC("test_ld", "ld 17,0(14)"); 1489 1490 extern void test_ldu (void); 1491 ASSEMBLY_FUNC("test_ldu", "ldu 17,0(14)"); 1492 1493 extern void test_lwa (void); 1494 ASSEMBLY_FUNC("test_lwa", "lwa 17,0(14)"); 1495 #endif // #ifdef __powerpc64__ 1496 1497 static test_t tests_ild_ops_two_i16[] = { 1498 { &test_lbz , " lbz", }, 1499 { &test_lbzu , " lbzu", }, 1500 { &test_lha , " lha", }, 1501 { &test_lhau , " lhau", }, 1502 { &test_lhz , " lhz", }, 1503 { &test_lhzu , " lhzu", }, 1504 { &test_lwz , " lwz", }, 1505 { &test_lwzu , " lwzu", }, 1506 #ifdef __powerpc64__ 1507 { &test_ld , " ld", }, 1508 { &test_ldu , " ldu", }, 1509 { &test_lwa , " lwa", }, 1510 #endif // #ifdef __powerpc64__ 1511 { NULL, NULL, }, 1512 }; 1513 1514 static void test_lbzx (void) 1515 { 1516 __asm__ __volatile__ ("lbzx 17,14,15"); 1517 } 1518 1519 static void test_lbzux (void) 1520 { 1521 __asm__ __volatile__ ("lbzux 17,14,15"); 1522 } 1523 1524 static void test_lhax (void) 1525 { 1526 __asm__ __volatile__ ("lhax 17,14,15"); 1527 } 1528 1529 static void test_lhaux (void) 1530 { 1531 __asm__ __volatile__ ("lhaux 17,14,15"); 1532 } 1533 1534 static void test_lhzx (void) 1535 { 1536 __asm__ __volatile__ ("lhzx 17,14,15"); 1537 } 1538 1539 static void test_lhzux (void) 1540 { 1541 __asm__ __volatile__ ("lhzux 17,14,15"); 1542 } 1543 1544 static void test_lwzx (void) 1545 { 1546 __asm__ __volatile__ ("lwzx 17,14,15"); 1547 } 1548 1549 static void test_lwzux (void) 1550 { 1551 __asm__ __volatile__ ("lwzux 17,14,15"); 1552 } 1553 1554 #ifdef __powerpc64__ 1555 static void test_ldx (void) 1556 { 1557 __asm__ __volatile__ ("ldx 17,14,15"); 1558 } 1559 1560 static void test_ldux (void) 1561 { 1562 __asm__ __volatile__ ("ldux 17,14,15"); 1563 } 1564 1565 static void test_lwax (void) 1566 { 1567 __asm__ __volatile__ ("lwax 17,14,15"); 1568 } 1569 1570 static void test_lwaux (void) 1571 { 1572 __asm__ __volatile__ ("lwaux 17,14,15"); 1573 } 1574 #endif // #ifdef __powerpc64__ 1575 1576 static test_t tests_ild_ops_two[] = { 1577 { &test_lbzx , " lbzx", }, 1578 { &test_lbzux , " lbzux", }, 1579 { &test_lhax , " lhax", }, 1580 { &test_lhaux , " lhaux", }, 1581 { &test_lhzx , " lhzx", }, 1582 { &test_lhzux , " lhzux", }, 1583 { &test_lwzx , " lwzx", }, 1584 { &test_lwzux , " lwzux", }, 1585 #ifdef __powerpc64__ 1586 { &test_ldx , " ldx", }, 1587 { &test_ldux , " ldux", }, 1588 { &test_lwax , " lwax", }, 1589 { &test_lwaux , " lwaux", }, 1590 #endif // #ifdef __powerpc64__ 1591 { NULL, NULL, }, 1592 }; 1593 1594 extern void test_stb (void); 1595 ASSEMBLY_FUNC("test_stb", "stb 14,0(15)"); 1596 1597 extern void test_stbu (void); 1598 ASSEMBLY_FUNC("test_stbu", "stbu 14,0(15)"); 1599 1600 extern void test_sth (void); 1601 ASSEMBLY_FUNC("test_sth", "sth 14,0(15)"); 1602 1603 extern void test_sthu (void); 1604 ASSEMBLY_FUNC("test_sthu", "sthu 14,0(15)"); 1605 1606 extern void test_stw (void); 1607 ASSEMBLY_FUNC("test_stw", "stw 14,0(15)"); 1608 1609 extern void test_stwu (void); 1610 ASSEMBLY_FUNC("test_stwu", "stwu 14,0(15)"); 1611 1612 #ifdef __powerpc64__ 1613 extern void test_std (void); 1614 ASSEMBLY_FUNC("test_std", "std 14,0(15)"); 1615 1616 extern void test_stdu (void); 1617 ASSEMBLY_FUNC("test_stdu", "stdu 14,0(15)"); 1618 #endif // #ifdef __powerpc64__ 1619 1620 static test_t tests_ist_ops_three_i16[] = { 1621 { &test_stb , " stb", }, 1622 { &test_stbu , " stbu", }, 1623 { &test_sth , " sth", }, 1624 { &test_sthu , " sthu", }, 1625 { &test_stw , " stw", }, 1626 { &test_stwu , " stwu", }, 1627 #ifdef __powerpc64__ 1628 { &test_std , " std", }, 1629 { &test_stdu , " stdu", }, 1630 #endif // #ifdef __powerpc64__ 1631 { NULL, NULL, }, 1632 }; 1633 1634 static void test_stbx (void) 1635 { 1636 __asm__ __volatile__ ("stbx 14,15,16"); 1637 } 1638 1639 static void test_stbux (void) 1640 { 1641 __asm__ __volatile__ ("stbux 14,15,16"); 1642 } 1643 1644 static void test_sthx (void) 1645 { 1646 __asm__ __volatile__ ("sthx 14,15,16"); 1647 } 1648 1649 static void test_sthux (void) 1650 { 1651 __asm__ __volatile__ ("sthux 14,15,16"); 1652 } 1653 1654 static void test_stwx (void) 1655 { 1656 __asm__ __volatile__ ("stwx 14,15,16"); 1657 } 1658 1659 static void test_stwux (void) 1660 { 1661 __asm__ __volatile__ ("stwux 14,15,16"); 1662 } 1663 1664 #ifdef __powerpc64__ 1665 static void test_stdx (void) 1666 { 1667 __asm__ __volatile__ ("stdx 14,15,16"); 1668 } 1669 1670 static void test_stdux (void) 1671 { 1672 __asm__ __volatile__ ("stdux 14,15,16"); 1673 } 1674 #endif // #ifdef __powerpc64__ 1675 1676 static test_t tests_ist_ops_three[] = { 1677 { &test_stbx , " stbx", }, 1678 { &test_stbux , " stbux", }, 1679 { &test_sthx , " sthx", }, 1680 { &test_sthux , " sthux", }, 1681 { &test_stwx , " stwx", }, 1682 { &test_stwux , " stwux", }, 1683 #ifdef __powerpc64__ 1684 { &test_stdx , " stdx", }, 1685 { &test_stdux , " stdux", }, 1686 #endif // #ifdef __powerpc64__ 1687 { NULL, NULL, }, 1688 }; 1689 1690 static void 1691 tests_popcnt_one(void) 1692 { 1693 __asm__ __volatile__ ("popcntb 17, 14"); 1694 } 1695 1696 static test_t tests_popcnt_ops_one[] = { 1697 { &tests_popcnt_one , " popcntb", }, 1698 { NULL, NULL, }, 1699 }; 1700 1701 #if !defined (NO_FLOAT) 1702 static void test_fsel (void) 1703 { 1704 __asm__ __volatile__ ("fsel 17, 14, 15, 16"); 1705 } 1706 1707 static void test_fmadd (void) 1708 { 1709 __asm__ __volatile__ ("fmadd 17, 14, 15, 16"); 1710 } 1711 1712 static void test_fmadds (void) 1713 { 1714 __asm__ __volatile__ ("fmadds 17, 14, 15, 16"); 1715 } 1716 1717 static void test_fmsub (void) 1718 { 1719 __asm__ __volatile__ ("fmsub 17, 14, 15, 16"); 1720 } 1721 1722 static void test_fmsubs (void) 1723 { 1724 __asm__ __volatile__ ("fmsubs 17, 14, 15, 16"); 1725 } 1726 1727 static void test_fnmadd (void) 1728 { 1729 __asm__ __volatile__ ("fnmadd 17, 14, 15, 16"); 1730 } 1731 1732 static void test_fnmadds (void) 1733 { 1734 __asm__ __volatile__ ("fnmadds 17, 14, 15, 16"); 1735 } 1736 1737 static void test_fnmsub (void) 1738 { 1739 __asm__ __volatile__ ("fnmsub 17, 14, 15, 16"); 1740 } 1741 1742 static void test_fnmsubs (void) 1743 { 1744 __asm__ __volatile__ ("fnmsubs 17, 14, 15, 16"); 1745 } 1746 1747 static test_t tests_fa_ops_three[] = { 1748 { &test_fsel , " fsel", }, 1749 { &test_fmadd , " fmadd", }, 1750 { &test_fmadds , " fmadds", }, 1751 { &test_fmsub , " fmsub", }, 1752 { &test_fmsubs , " fmsubs", }, 1753 { &test_fnmadd , " fnmadd", }, 1754 { &test_fnmadds , " fnmadds", }, 1755 { &test_fnmsub , " fnmsub", }, 1756 { &test_fnmsubs , " fnmsubs", }, 1757 { NULL, NULL, }, 1758 }; 1759 #endif /* !defined (NO_FLOAT) */ 1760 1761 #if !defined (NO_FLOAT) 1762 static void test_fsel_ (void) 1763 { 1764 __asm__ __volatile__ ("fsel. 17, 14, 15, 16"); 1765 } 1766 1767 static void test_fmadd_ (void) 1768 { 1769 __asm__ __volatile__ ("fmadd. 17, 14, 15, 16"); 1770 } 1771 1772 static void test_fmadds_ (void) 1773 { 1774 __asm__ __volatile__ ("fmadds. 17, 14, 15, 16"); 1775 } 1776 1777 static void test_fmsub_ (void) 1778 { 1779 __asm__ __volatile__ ("fmsub. 17, 14, 15, 16"); 1780 } 1781 1782 static void test_fmsubs_ (void) 1783 { 1784 __asm__ __volatile__ ("fmsubs. 17, 14, 15, 16"); 1785 } 1786 1787 static void test_fnmadd_ (void) 1788 { 1789 __asm__ __volatile__ ("fnmadd. 17, 14, 15, 16"); 1790 } 1791 1792 static void test_fnmadds_ (void) 1793 { 1794 __asm__ __volatile__ ("fnmadds. 17, 14, 15, 16"); 1795 } 1796 1797 static void test_fnmsub_ (void) 1798 { 1799 __asm__ __volatile__ ("fnmsub. 17, 14, 15, 16"); 1800 } 1801 1802 static void test_fnmsubs_ (void) 1803 { 1804 __asm__ __volatile__ ("fnmsubs. 17, 14, 15, 16"); 1805 } 1806 1807 static test_t tests_far_ops_three[] = { 1808 { &test_fsel_ , " fsel.", }, 1809 { &test_fmadd_ , " fmadd.", }, 1810 { &test_fmadds_ , " fmadds.", }, 1811 { &test_fmsub_ , " fmsub.", }, 1812 { &test_fmsubs_ , " fmsubs.", }, 1813 { &test_fnmadd_ , " fnmadd.", }, 1814 { &test_fnmadds_ , " fnmadds.", }, 1815 { &test_fnmsub_ , " fnmsub.", }, 1816 { &test_fnmsubs_ , " fnmsubs.", }, 1817 { NULL, NULL, }, 1818 }; 1819 #endif /* !defined (NO_FLOAT) */ 1820 1821 #if !defined (NO_FLOAT) 1822 static void test_fadd (void) 1823 { 1824 __asm__ __volatile__ ("fadd 17, 14, 15"); 1825 } 1826 1827 static void test_fadds (void) 1828 { 1829 __asm__ __volatile__ ("fadds 17, 14, 15"); 1830 } 1831 1832 static void test_fsub (void) 1833 { 1834 __asm__ __volatile__ ("fsub 17, 14, 15"); 1835 } 1836 1837 static void test_fsubs (void) 1838 { 1839 __asm__ __volatile__ ("fsubs 17, 14, 15"); 1840 } 1841 1842 static void test_fmul (void) 1843 { 1844 __asm__ __volatile__ ("fmul 17, 14, 15"); 1845 } 1846 1847 static void test_fmuls (void) 1848 { 1849 __asm__ __volatile__ ("fmuls 17, 14, 15"); 1850 } 1851 1852 static void test_fdiv (void) 1853 { 1854 __asm__ __volatile__ ("fdiv 17, 14, 15"); 1855 } 1856 1857 static void test_fdivs (void) 1858 { 1859 __asm__ __volatile__ ("fdivs 17, 14, 15"); 1860 } 1861 1862 static test_t tests_fa_ops_two[] = { 1863 { &test_fadd , " fadd", }, 1864 { &test_fadds , " fadds", }, 1865 { &test_fsub , " fsub", }, 1866 { &test_fsubs , " fsubs", }, 1867 { &test_fmul , " fmul", }, 1868 { &test_fmuls , " fmuls", }, 1869 { &test_fdiv , " fdiv", }, 1870 { &test_fdivs , " fdivs", }, 1871 { NULL, NULL, }, 1872 }; 1873 #endif /* !defined (NO_FLOAT) */ 1874 1875 #if !defined (NO_FLOAT) 1876 static void test_fadd_ (void) 1877 { 1878 __asm__ __volatile__ ("fadd. 17, 14, 15"); 1879 } 1880 1881 static void test_fadds_ (void) 1882 { 1883 __asm__ __volatile__ ("fadds. 17, 14, 15"); 1884 } 1885 1886 static void test_fsub_ (void) 1887 { 1888 __asm__ __volatile__ ("fsub. 17, 14, 15"); 1889 } 1890 1891 static void test_fsubs_ (void) 1892 { 1893 __asm__ __volatile__ ("fsubs. 17, 14, 15"); 1894 } 1895 1896 static void test_fmul_ (void) 1897 { 1898 __asm__ __volatile__ ("fmul. 17, 14, 15"); 1899 } 1900 1901 static void test_fmuls_ (void) 1902 { 1903 __asm__ __volatile__ ("fmuls. 17, 14, 15"); 1904 } 1905 1906 static void test_fdiv_ (void) 1907 { 1908 __asm__ __volatile__ ("fdiv. 17, 14, 15"); 1909 } 1910 1911 static void test_fdivs_ (void) 1912 { 1913 __asm__ __volatile__ ("fdivs. 17, 14, 15"); 1914 } 1915 1916 static test_t tests_far_ops_two[] = { 1917 { &test_fadd_ , " fadd.", }, 1918 { &test_fadds_ , " fadds.", }, 1919 { &test_fsub_ , " fsub.", }, 1920 { &test_fsubs_ , " fsubs.", }, 1921 { &test_fmul_ , " fmul.", }, 1922 { &test_fmuls_ , " fmuls.", }, 1923 { &test_fdiv_ , " fdiv.", }, 1924 { &test_fdivs_ , " fdivs.", }, 1925 { NULL, NULL, }, 1926 }; 1927 #endif /* !defined (NO_FLOAT) */ 1928 1929 #if !defined (NO_FLOAT) 1930 static void test_fcmpo (void) 1931 { 1932 __asm__ __volatile__ ("fcmpo 2, 14, 15"); 1933 } 1934 1935 static void test_fcmpu (void) 1936 { 1937 __asm__ __volatile__ ("fcmpu 2, 14, 15"); 1938 } 1939 1940 static test_t tests_fcr_ops_two[] = { 1941 { &test_fcmpo , " fcmpo", }, 1942 { &test_fcmpu , " fcmpu", }, 1943 { NULL, NULL, }, 1944 }; 1945 #endif /* !defined (NO_FLOAT) */ 1946 1947 #if !defined (NO_FLOAT) 1948 1949 static void test_fres (void) 1950 { 1951 __asm__ __volatile__ ("fres 17, 14"); 1952 } 1953 1954 static void test_frsqrte (void) 1955 { 1956 __asm__ __volatile__ ("frsqrte 17, 14"); 1957 } 1958 1959 static void test_frsp (void) 1960 { 1961 __asm__ __volatile__ ("frsp 17, 14"); 1962 } 1963 1964 static void test_fctiw (void) 1965 { 1966 __asm__ __volatile__ ("fctiw 17, 14"); 1967 } 1968 1969 static void test_fctiwz (void) 1970 { 1971 __asm__ __volatile__ ("fctiwz 17, 14"); 1972 } 1973 1974 static void test_fmr (void) 1975 { 1976 __asm__ __volatile__ ("fmr 17, 14"); 1977 } 1978 1979 static void test_fneg (void) 1980 { 1981 __asm__ __volatile__ ("fneg 17, 14"); 1982 } 1983 1984 static void test_fabs (void) 1985 { 1986 __asm__ __volatile__ ("fabs 17, 14"); 1987 } 1988 1989 static void test_fnabs (void) 1990 { 1991 __asm__ __volatile__ ("fnabs 17, 14"); 1992 } 1993 1994 static void test_fsqrt (void) 1995 { 1996 __asm__ __volatile__ ("fsqrt 17, 14"); 1997 } 1998 1999 #ifdef __powerpc64__ 2000 static void test_fcfid (void) 2001 { 2002 __asm__ __volatile__ ("fcfid 17, 14"); 2003 } 2004 2005 static void test_fctid (void) 2006 { 2007 __asm__ __volatile__ ("fctid 17, 14"); 2008 } 2009 2010 static void test_fctidz (void) 2011 { 2012 __asm__ __volatile__ ("fctidz 17, 14"); 2013 } 2014 #endif // #ifdef __powerpc64__ 2015 2016 static test_t tests_fa_ops_one[] = { 2017 { &test_fres , " fres", }, 2018 { &test_frsqrte , " frsqrte", }, 2019 { &test_frsp , " frsp", }, 2020 { &test_fctiw , " fctiw", }, 2021 { &test_fctiwz , " fctiwz", }, 2022 { &test_fmr , " fmr", }, 2023 { &test_fneg , " fneg", }, 2024 { &test_fabs , " fabs", }, 2025 { &test_fnabs , " fnabs", }, 2026 { &test_fsqrt , " fsqrt", }, 2027 #ifdef __powerpc64__ 2028 { &test_fcfid , " fcfid", }, 2029 { &test_fctid , " fctid", }, 2030 { &test_fctidz , " fctidz", }, 2031 #endif // #ifdef __powerpc64__ 2032 { NULL, NULL, }, 2033 }; 2034 #endif /* !defined (NO_FLOAT) */ 2035 2036 #if !defined (NO_FLOAT) 2037 2038 static void test_fres_ (void) 2039 { 2040 __asm__ __volatile__ ("fres. 17, 14"); 2041 } 2042 2043 static void test_frsqrte_ (void) 2044 { 2045 __asm__ __volatile__ ("frsqrte. 17, 14"); 2046 } 2047 2048 static void test_frsp_ (void) 2049 { 2050 __asm__ __volatile__ ("frsp. 17, 14"); 2051 } 2052 2053 static void test_fctiw_ (void) 2054 { 2055 __asm__ __volatile__ ("fctiw. 17, 14"); 2056 } 2057 2058 static void test_fctiwz_ (void) 2059 { 2060 __asm__ __volatile__ ("fctiwz. 17, 14"); 2061 } 2062 2063 static void test_fmr_ (void) 2064 { 2065 __asm__ __volatile__ ("fmr. 17, 14"); 2066 } 2067 2068 static void test_fneg_ (void) 2069 { 2070 __asm__ __volatile__ ("fneg. 17, 14"); 2071 } 2072 2073 static void test_fabs_ (void) 2074 { 2075 __asm__ __volatile__ ("fabs. 17, 14"); 2076 } 2077 2078 static void test_fnabs_ (void) 2079 { 2080 __asm__ __volatile__ ("fnabs. 17, 14"); 2081 } 2082 2083 #ifdef __powerpc64__ 2084 static void test_fcfid_ (void) 2085 { 2086 __asm__ __volatile__ ("fcfid. 17, 14"); 2087 } 2088 2089 static void test_fctid_ (void) 2090 { 2091 __asm__ __volatile__ ("fctid. 17, 14"); 2092 } 2093 2094 static void test_fctidz_ (void) 2095 { 2096 __asm__ __volatile__ ("fctidz. 17, 14"); 2097 } 2098 #endif // #ifdef __powerpc64__ 2099 2100 static test_t tests_far_ops_one[] = { 2101 { &test_fres_ , " fres.", }, 2102 { &test_frsqrte_ , " frsqrte.", }, 2103 { &test_frsp_ , " frsp.", }, 2104 { &test_fctiw_ , " fctiw.", }, 2105 { &test_fctiwz_ , " fctiwz.", }, 2106 { &test_fmr_ , " fmr.", }, 2107 { &test_fneg_ , " fneg.", }, 2108 { &test_fabs_ , " fabs.", }, 2109 { &test_fnabs_ , " fnabs.", }, 2110 #ifdef __powerpc64__ 2111 { &test_fcfid_ , " fcfid.", }, 2112 { &test_fctid_ , " fctid.", }, 2113 { &test_fctidz_ , " fctidz.", }, 2114 #endif // #ifdef __powerpc64__ 2115 { NULL, NULL, }, 2116 }; 2117 #endif /* !defined (NO_FLOAT) */ 2118 2119 #if !defined (NO_FLOAT) 2120 static test_t tests_fl_ops_spe[] = { 2121 { NULL, NULL, }, 2122 }; 2123 #endif /* !defined (NO_FLOAT) */ 2124 2125 #if !defined (NO_FLOAT) 2126 static test_t tests_flr_ops_spe[] = { 2127 { NULL, NULL, }, 2128 }; 2129 #endif /* !defined (NO_FLOAT) */ 2130 2131 2132 #if !defined (NO_FLOAT) 2133 extern void test_lfs (void); 2134 ASSEMBLY_FUNC("test_lfs", "lfs 17,0(14)"); 2135 2136 extern void test_lfsu (void); 2137 ASSEMBLY_FUNC("test_lfsu", "lfsu 17,0(14)"); 2138 2139 extern void test_lfd (void); 2140 ASSEMBLY_FUNC("test_lfd", "lfd 17,0(14)"); 2141 2142 extern void test_lfdu (void); 2143 ASSEMBLY_FUNC("test_lfdu", "lfdu 17,0(14)"); 2144 2145 static test_t tests_fld_ops_two_i16[] = { 2146 { &test_lfs , " lfs", }, 2147 { &test_lfsu , " lfsu", }, 2148 { &test_lfd , " lfd", }, 2149 { &test_lfdu , " lfdu", }, 2150 { NULL, NULL, }, 2151 }; 2152 #endif /* !defined (NO_FLOAT) */ 2153 2154 #if !defined (NO_FLOAT) 2155 static void test_lfsx (void) 2156 { 2157 __asm__ __volatile__ ("lfsx 17,14,15"); 2158 } 2159 2160 static void test_lfsux (void) 2161 { 2162 __asm__ __volatile__ ("lfsux 17,14,15"); 2163 } 2164 2165 static void test_lfdx (void) 2166 { 2167 __asm__ __volatile__ ("lfdx 17,14,15"); 2168 } 2169 2170 static void test_lfdux (void) 2171 { 2172 __asm__ __volatile__ ("lfdux 17,14,15"); 2173 } 2174 2175 static test_t tests_fld_ops_two[] = { 2176 { &test_lfsx , " lfsx", }, 2177 { &test_lfsux , " lfsux", }, 2178 { &test_lfdx , " lfdx", }, 2179 { &test_lfdux , " lfdux", }, 2180 { NULL, NULL, }, 2181 }; 2182 #endif /* !defined (NO_FLOAT) */ 2183 2184 #if !defined (NO_FLOAT) 2185 extern void test_stfs (void); 2186 ASSEMBLY_FUNC("test_stfs", "stfs 14,0(15)"); 2187 2188 extern void test_stfsu (void); 2189 ASSEMBLY_FUNC("test_stfsu", "stfsu 14,0(15)"); 2190 2191 extern void test_stfd (void); 2192 ASSEMBLY_FUNC("test_stfd", "stfd 14,0(15)"); 2193 2194 extern void test_stfdu (void); 2195 ASSEMBLY_FUNC("test_stfdu", "stfdu 14,0(15)"); 2196 2197 static test_t tests_fst_ops_three_i16[] = { 2198 { &test_stfs , " stfs", }, 2199 { &test_stfsu , " stfsu", }, 2200 { &test_stfd , " stfd", }, 2201 { &test_stfdu , " stfdu", }, 2202 { NULL, NULL, }, 2203 }; 2204 #endif /* !defined (NO_FLOAT) */ 2205 2206 #if !defined (NO_FLOAT) 2207 static void test_stfsx (void) 2208 { 2209 __asm__ __volatile__ ("stfsx 14,15,16"); 2210 } 2211 2212 static void test_stfsux (void) 2213 { 2214 __asm__ __volatile__ ("stfsux 14,15,16"); 2215 } 2216 2217 static void test_stfdx (void) 2218 { 2219 __asm__ __volatile__ ("stfdx 14,15,16"); 2220 } 2221 2222 static void test_stfdux (void) 2223 { 2224 __asm__ __volatile__ ("stfdux 14,15,16"); 2225 } 2226 2227 static test_t tests_fst_ops_three[] = { 2228 { &test_stfsx , " stfsx", }, 2229 { &test_stfsux , " stfsux", }, 2230 { &test_stfdx , " stfdx", }, 2231 { &test_stfdux , " stfdux", }, 2232 { NULL, NULL, }, 2233 }; 2234 #endif /* !defined (NO_FLOAT) */ 2235 2236 2237 #if defined (HAS_ALTIVEC) 2238 static void test_vmhaddshs (void) 2239 { 2240 __asm__ __volatile__ ("vmhaddshs 17, 14, 15, 16"); 2241 } 2242 2243 static void test_vmhraddshs (void) 2244 { 2245 __asm__ __volatile__ ("vmhraddshs 17, 14, 15, 16"); 2246 } 2247 2248 static void test_vmladduhm (void) 2249 { 2250 __asm__ __volatile__ ("vmladduhm 17, 14, 15, 16"); 2251 } 2252 2253 static void test_vmsumubm (void) 2254 { 2255 __asm__ __volatile__ ("vmsumubm 17, 14, 15, 16"); 2256 } 2257 2258 static void test_vmsumuhm (void) 2259 { 2260 __asm__ __volatile__ ("vmsumuhm 17, 14, 15, 16"); 2261 } 2262 2263 static void test_vmsumshs (void) 2264 { 2265 __asm__ __volatile__ ("vmsumshs 17, 14, 15, 16"); 2266 } 2267 2268 static void test_vmsumuhs (void) 2269 { 2270 __asm__ __volatile__ ("vmsumuhs 17, 14, 15, 16"); 2271 } 2272 2273 static void test_vmsummbm (void) 2274 { 2275 __asm__ __volatile__ ("vmsummbm 17, 14, 15, 16"); 2276 } 2277 2278 static void test_vmsumshm (void) 2279 { 2280 __asm__ __volatile__ ("vmsumshm 17, 14, 15, 16"); 2281 } 2282 2283 static test_t tests_aa_ops_three[] = { 2284 { &test_vmhaddshs , " vmhaddshs", }, 2285 { &test_vmhraddshs , " vmhraddshs", }, 2286 { &test_vmladduhm , " vmladduhm", }, 2287 { &test_vmsumubm , " vmsumubm", }, 2288 { &test_vmsumuhm , " vmsumuhm", }, 2289 { &test_vmsumshs , " vmsumshs", }, 2290 { &test_vmsumuhs , " vmsumuhs", }, 2291 { &test_vmsummbm , " vmsummbm", }, 2292 { &test_vmsumshm , " vmsumshm", }, 2293 { NULL, NULL, }, 2294 }; 2295 #endif /* defined (HAS_ALTIVEC) */ 2296 2297 #if defined (HAS_ALTIVEC) 2298 static void test_vperm (void) 2299 { 2300 __asm__ __volatile__ ("vperm 17, 14, 15, 16"); 2301 } 2302 2303 static void test_vsel (void) 2304 { 2305 __asm__ __volatile__ ("vsel 17, 14, 15, 16"); 2306 } 2307 2308 static test_t tests_al_ops_three[] = { 2309 { &test_vperm , " vperm", }, 2310 { &test_vsel , " vsel", }, 2311 { NULL, NULL, }, 2312 }; 2313 #endif /* defined (HAS_ALTIVEC) */ 2314 2315 #if defined (HAS_ALTIVEC) 2316 static void test_vaddubm (void) 2317 { 2318 __asm__ __volatile__ ("vaddubm 17, 14, 15"); 2319 } 2320 2321 static void test_vadduhm (void) 2322 { 2323 __asm__ __volatile__ ("vadduhm 17, 14, 15"); 2324 } 2325 2326 static void test_vadduwm (void) 2327 { 2328 __asm__ __volatile__ ("vadduwm 17, 14, 15"); 2329 } 2330 2331 static void test_vaddubs (void) 2332 { 2333 __asm__ __volatile__ ("vaddubs 17, 14, 15"); 2334 } 2335 2336 static void test_vadduhs (void) 2337 { 2338 __asm__ __volatile__ ("vadduhs 17, 14, 15"); 2339 } 2340 2341 static void test_vadduws (void) 2342 { 2343 __asm__ __volatile__ ("vadduws 17, 14, 15"); 2344 } 2345 2346 static void test_vaddsbs (void) 2347 { 2348 __asm__ __volatile__ ("vaddsbs 17, 14, 15"); 2349 } 2350 2351 static void test_vaddshs (void) 2352 { 2353 __asm__ __volatile__ ("vaddshs 17, 14, 15"); 2354 } 2355 2356 static void test_vaddsws (void) 2357 { 2358 __asm__ __volatile__ ("vaddsws 17, 14, 15"); 2359 } 2360 2361 static void test_vaddcuw (void) 2362 { 2363 __asm__ __volatile__ ("vaddcuw 17, 14, 15"); 2364 } 2365 2366 static void test_vsububm (void) 2367 { 2368 __asm__ __volatile__ ("vsububm 17, 14, 15"); 2369 } 2370 2371 static void test_vsubuhm (void) 2372 { 2373 __asm__ __volatile__ ("vsubuhm 17, 14, 15"); 2374 } 2375 2376 static void test_vsubuwm (void) 2377 { 2378 __asm__ __volatile__ ("vsubuwm 17, 14, 15"); 2379 } 2380 2381 static void test_vsububs (void) 2382 { 2383 __asm__ __volatile__ ("vsububs 17, 14, 15"); 2384 } 2385 2386 static void test_vsubuhs (void) 2387 { 2388 __asm__ __volatile__ ("vsubuhs 17, 14, 15"); 2389 } 2390 2391 static void test_vsubuws (void) 2392 { 2393 __asm__ __volatile__ ("vsubuws 17, 14, 15"); 2394 } 2395 2396 static void test_vsubsbs (void) 2397 { 2398 __asm__ __volatile__ ("vsubsbs 17, 14, 15"); 2399 } 2400 2401 static void test_vsubshs (void) 2402 { 2403 __asm__ __volatile__ ("vsubshs 17, 14, 15"); 2404 } 2405 2406 static void test_vsubsws (void) 2407 { 2408 __asm__ __volatile__ ("vsubsws 17, 14, 15"); 2409 } 2410 2411 static void test_vsubcuw (void) 2412 { 2413 __asm__ __volatile__ ("vsubcuw 17, 14, 15"); 2414 } 2415 2416 static void test_vmuloub (void) 2417 { 2418 __asm__ __volatile__ ("vmuloub 17, 14, 15"); 2419 } 2420 2421 static void test_vmulouh (void) 2422 { 2423 __asm__ __volatile__ ("vmulouh 17, 14, 15"); 2424 } 2425 2426 static void test_vmulosb (void) 2427 { 2428 __asm__ __volatile__ ("vmulosb 17, 14, 15"); 2429 } 2430 2431 static void test_vmulosh (void) 2432 { 2433 __asm__ __volatile__ ("vmulosh 17, 14, 15"); 2434 } 2435 2436 static void test_vmuleub (void) 2437 { 2438 __asm__ __volatile__ ("vmuleub 17, 14, 15"); 2439 } 2440 2441 static void test_vmuleuh (void) 2442 { 2443 __asm__ __volatile__ ("vmuleuh 17, 14, 15"); 2444 } 2445 2446 static void test_vmulesb (void) 2447 { 2448 __asm__ __volatile__ ("vmulesb 17, 14, 15"); 2449 } 2450 2451 static void test_vmulesh (void) 2452 { 2453 __asm__ __volatile__ ("vmulesh 17, 14, 15"); 2454 } 2455 2456 static void test_vsumsws (void) 2457 { 2458 __asm__ __volatile__ ("vsumsws 17, 14, 15"); 2459 } 2460 2461 static void test_vsum2sws (void) 2462 { 2463 __asm__ __volatile__ ("vsum2sws 17, 14, 15"); 2464 } 2465 2466 static void test_vsum4ubs (void) 2467 { 2468 __asm__ __volatile__ ("vsum4ubs 17, 14, 15"); 2469 } 2470 2471 static void test_vsum4sbs (void) 2472 { 2473 __asm__ __volatile__ ("vsum4sbs 17, 14, 15"); 2474 } 2475 2476 static void test_vsum4shs (void) 2477 { 2478 __asm__ __volatile__ ("vsum4shs 17, 14, 15"); 2479 } 2480 2481 static void test_vavgub (void) 2482 { 2483 __asm__ __volatile__ ("vavgub 17, 14, 15"); 2484 } 2485 2486 static void test_vavguh (void) 2487 { 2488 __asm__ __volatile__ ("vavguh 17, 14, 15"); 2489 } 2490 2491 static void test_vavguw (void) 2492 { 2493 __asm__ __volatile__ ("vavguw 17, 14, 15"); 2494 } 2495 2496 static void test_vavgsb (void) 2497 { 2498 __asm__ __volatile__ ("vavgsb 17, 14, 15"); 2499 } 2500 2501 static void test_vavgsh (void) 2502 { 2503 __asm__ __volatile__ ("vavgsh 17, 14, 15"); 2504 } 2505 2506 static void test_vavgsw (void) 2507 { 2508 __asm__ __volatile__ ("vavgsw 17, 14, 15"); 2509 } 2510 2511 static void test_vmaxub (void) 2512 { 2513 __asm__ __volatile__ ("vmaxub 17, 14, 15"); 2514 } 2515 2516 static void test_vmaxuh (void) 2517 { 2518 __asm__ __volatile__ ("vmaxuh 17, 14, 15"); 2519 } 2520 2521 static void test_vmaxuw (void) 2522 { 2523 __asm__ __volatile__ ("vmaxuw 17, 14, 15"); 2524 } 2525 2526 static void test_vmaxsb (void) 2527 { 2528 __asm__ __volatile__ ("vmaxsb 17, 14, 15"); 2529 } 2530 2531 static void test_vmaxsh (void) 2532 { 2533 __asm__ __volatile__ ("vmaxsh 17, 14, 15"); 2534 } 2535 2536 static void test_vmaxsw (void) 2537 { 2538 __asm__ __volatile__ ("vmaxsw 17, 14, 15"); 2539 } 2540 2541 static void test_vminub (void) 2542 { 2543 __asm__ __volatile__ ("vminub 17, 14, 15"); 2544 } 2545 2546 static void test_vminuh (void) 2547 { 2548 __asm__ __volatile__ ("vminuh 17, 14, 15"); 2549 } 2550 2551 static void test_vminuw (void) 2552 { 2553 __asm__ __volatile__ ("vminuw 17, 14, 15"); 2554 } 2555 2556 static void test_vminsb (void) 2557 { 2558 __asm__ __volatile__ ("vminsb 17, 14, 15"); 2559 } 2560 2561 static void test_vminsh (void) 2562 { 2563 __asm__ __volatile__ ("vminsh 17, 14, 15"); 2564 } 2565 2566 static void test_vminsw (void) 2567 { 2568 __asm__ __volatile__ ("vminsw 17, 14, 15"); 2569 } 2570 2571 static test_t tests_aa_ops_two[] = { 2572 { &test_vaddubm , " vaddubm", }, 2573 { &test_vadduhm , " vadduhm", }, 2574 { &test_vadduwm , " vadduwm", }, 2575 { &test_vaddubs , " vaddubs", }, 2576 { &test_vadduhs , " vadduhs", }, 2577 { &test_vadduws , " vadduws", }, 2578 { &test_vaddsbs , " vaddsbs", }, 2579 { &test_vaddshs , " vaddshs", }, 2580 { &test_vaddsws , " vaddsws", }, 2581 { &test_vaddcuw , " vaddcuw", }, 2582 { &test_vsububm , " vsububm", }, 2583 { &test_vsubuhm , " vsubuhm", }, 2584 { &test_vsubuwm , " vsubuwm", }, 2585 { &test_vsububs , " vsububs", }, 2586 { &test_vsubuhs , " vsubuhs", }, 2587 { &test_vsubuws , " vsubuws", }, 2588 { &test_vsubsbs , " vsubsbs", }, 2589 { &test_vsubshs , " vsubshs", }, 2590 { &test_vsubsws , " vsubsws", }, 2591 { &test_vsubcuw , " vsubcuw", }, 2592 { &test_vmuloub , " vmuloub", }, 2593 { &test_vmulouh , " vmulouh", }, 2594 { &test_vmulosb , " vmulosb", }, 2595 { &test_vmulosh , " vmulosh", }, 2596 { &test_vmuleub , " vmuleub", }, 2597 { &test_vmuleuh , " vmuleuh", }, 2598 { &test_vmulesb , " vmulesb", }, 2599 { &test_vmulesh , " vmulesh", }, 2600 { &test_vsumsws , " vsumsws", }, 2601 { &test_vsum2sws , " vsum2sws", }, 2602 { &test_vsum4ubs , " vsum4ubs", }, 2603 { &test_vsum4sbs , " vsum4sbs", }, 2604 { &test_vsum4shs , " vsum4shs", }, 2605 { &test_vavgub , " vavgub", }, 2606 { &test_vavguh , " vavguh", }, 2607 { &test_vavguw , " vavguw", }, 2608 { &test_vavgsb , " vavgsb", }, 2609 { &test_vavgsh , " vavgsh", }, 2610 { &test_vavgsw , " vavgsw", }, 2611 { &test_vmaxub , " vmaxub", }, 2612 { &test_vmaxuh , " vmaxuh", }, 2613 { &test_vmaxuw , " vmaxuw", }, 2614 { &test_vmaxsb , " vmaxsb", }, 2615 { &test_vmaxsh , " vmaxsh", }, 2616 { &test_vmaxsw , " vmaxsw", }, 2617 { &test_vminub , " vminub", }, 2618 { &test_vminuh , " vminuh", }, 2619 { &test_vminuw , " vminuw", }, 2620 { &test_vminsb , " vminsb", }, 2621 { &test_vminsh , " vminsh", }, 2622 { &test_vminsw , " vminsw", }, 2623 { NULL, NULL, }, 2624 }; 2625 #endif /* defined (HAS_ALTIVEC) */ 2626 2627 #if defined (HAS_ALTIVEC) 2628 static void test_vand (void) 2629 { 2630 __asm__ __volatile__ ("vand 17, 14, 15"); 2631 } 2632 2633 static void test_vor (void) 2634 { 2635 __asm__ __volatile__ ("vor 17, 14, 15"); 2636 } 2637 2638 static void test_vxor (void) 2639 { 2640 __asm__ __volatile__ ("vxor 17, 14, 15"); 2641 } 2642 2643 static void test_vandc (void) 2644 { 2645 __asm__ __volatile__ ("vandc 17, 14, 15"); 2646 } 2647 2648 static void test_vnor (void) 2649 { 2650 __asm__ __volatile__ ("vnor 17, 14, 15"); 2651 } 2652 2653 static void test_vrlb (void) 2654 { 2655 __asm__ __volatile__ ("vrlb 17, 14, 15"); 2656 } 2657 2658 static void test_vrlh (void) 2659 { 2660 __asm__ __volatile__ ("vrlh 17, 14, 15"); 2661 } 2662 2663 static void test_vrlw (void) 2664 { 2665 __asm__ __volatile__ ("vrlw 17, 14, 15"); 2666 } 2667 2668 static void test_vslb (void) 2669 { 2670 __asm__ __volatile__ ("vslb 17, 14, 15"); 2671 } 2672 2673 static void test_vslh (void) 2674 { 2675 __asm__ __volatile__ ("vslh 17, 14, 15"); 2676 } 2677 2678 static void test_vslw (void) 2679 { 2680 __asm__ __volatile__ ("vslw 17, 14, 15"); 2681 } 2682 2683 static void test_vsrb (void) 2684 { 2685 __asm__ __volatile__ ("vsrb 17, 14, 15"); 2686 } 2687 2688 static void test_vsrh (void) 2689 { 2690 __asm__ __volatile__ ("vsrh 17, 14, 15"); 2691 } 2692 2693 static void test_vsrw (void) 2694 { 2695 __asm__ __volatile__ ("vsrw 17, 14, 15"); 2696 } 2697 2698 static void test_vsrab (void) 2699 { 2700 __asm__ __volatile__ ("vsrab 17, 14, 15"); 2701 } 2702 2703 static void test_vsrah (void) 2704 { 2705 __asm__ __volatile__ ("vsrah 17, 14, 15"); 2706 } 2707 2708 static void test_vsraw (void) 2709 { 2710 __asm__ __volatile__ ("vsraw 17, 14, 15"); 2711 } 2712 2713 static void test_vpkuhum (void) 2714 { 2715 __asm__ __volatile__ ("vpkuhum 17, 14, 15"); 2716 } 2717 2718 static void test_vpkuwum (void) 2719 { 2720 __asm__ __volatile__ ("vpkuwum 17, 14, 15"); 2721 } 2722 2723 static void test_vpkuhus (void) 2724 { 2725 __asm__ __volatile__ ("vpkuhus 17, 14, 15"); 2726 } 2727 2728 static void test_vpkuwus (void) 2729 { 2730 __asm__ __volatile__ ("vpkuwus 17, 14, 15"); 2731 } 2732 2733 static void test_vpkshus (void) 2734 { 2735 __asm__ __volatile__ ("vpkshus 17, 14, 15"); 2736 } 2737 2738 static void test_vpkswus (void) 2739 { 2740 __asm__ __volatile__ ("vpkswus 17, 14, 15"); 2741 } 2742 2743 static void test_vpkshss (void) 2744 { 2745 __asm__ __volatile__ ("vpkshss 17, 14, 15"); 2746 } 2747 2748 static void test_vpkswss (void) 2749 { 2750 __asm__ __volatile__ ("vpkswss 17, 14, 15"); 2751 } 2752 2753 static void test_vpkpx (void) 2754 { 2755 __asm__ __volatile__ ("vpkpx 17, 14, 15"); 2756 } 2757 2758 static void test_vmrghb (void) 2759 { 2760 __asm__ __volatile__ ("vmrghb 17, 14, 15"); 2761 } 2762 2763 static void test_vmrghh (void) 2764 { 2765 __asm__ __volatile__ ("vmrghh 17, 14, 15"); 2766 } 2767 2768 static void test_vmrghw (void) 2769 { 2770 __asm__ __volatile__ ("vmrghw 17, 14, 15"); 2771 } 2772 2773 static void test_vmrglb (void) 2774 { 2775 __asm__ __volatile__ ("vmrglb 17, 14, 15"); 2776 } 2777 2778 static void test_vmrglh (void) 2779 { 2780 __asm__ __volatile__ ("vmrglh 17, 14, 15"); 2781 } 2782 2783 static void test_vmrglw (void) 2784 { 2785 __asm__ __volatile__ ("vmrglw 17, 14, 15"); 2786 } 2787 2788 static void test_vslo (void) 2789 { 2790 __asm__ __volatile__ ("vslo 17, 14, 15"); 2791 } 2792 2793 static void test_vsro (void) 2794 { 2795 __asm__ __volatile__ ("vsro 17, 14, 15"); 2796 } 2797 2798 static test_t tests_al_ops_two[] = { 2799 { &test_vand , " vand", }, 2800 { &test_vor , " vor", }, 2801 { &test_vxor , " vxor", }, 2802 { &test_vandc , " vandc", }, 2803 { &test_vnor , " vnor", }, 2804 { &test_vrlb , " vrlb", }, 2805 { &test_vrlh , " vrlh", }, 2806 { &test_vrlw , " vrlw", }, 2807 { &test_vslb , " vslb", }, 2808 { &test_vslh , " vslh", }, 2809 { &test_vslw , " vslw", }, 2810 { &test_vsrb , " vsrb", }, 2811 { &test_vsrh , " vsrh", }, 2812 { &test_vsrw , " vsrw", }, 2813 { &test_vsrab , " vsrab", }, 2814 { &test_vsrah , " vsrah", }, 2815 { &test_vsraw , " vsraw", }, 2816 { &test_vpkuhum , " vpkuhum", }, 2817 { &test_vpkuwum , " vpkuwum", }, 2818 { &test_vpkuhus , " vpkuhus", }, 2819 { &test_vpkuwus , " vpkuwus", }, 2820 { &test_vpkshus , " vpkshus", }, 2821 { &test_vpkswus , " vpkswus", }, 2822 { &test_vpkshss , " vpkshss", }, 2823 { &test_vpkswss , " vpkswss", }, 2824 { &test_vpkpx , " vpkpx", }, 2825 { &test_vmrghb , " vmrghb", }, 2826 { &test_vmrghh , " vmrghh", }, 2827 { &test_vmrghw , " vmrghw", }, 2828 { &test_vmrglb , " vmrglb", }, 2829 { &test_vmrglh , " vmrglh", }, 2830 { &test_vmrglw , " vmrglw", }, 2831 { &test_vslo , " vslo", }, 2832 { &test_vsro , " vsro", }, 2833 { NULL, NULL, }, 2834 }; 2835 #endif /* defined (HAS_ALTIVEC) */ 2836 2837 #if defined (HAS_ALTIVEC) 2838 static void test_vupkhsb (void) 2839 { 2840 __asm__ __volatile__ ("vupkhsb 17, 14"); 2841 } 2842 2843 static void test_vupkhsh (void) 2844 { 2845 __asm__ __volatile__ ("vupkhsh 17, 14"); 2846 } 2847 2848 static void test_vupkhpx (void) 2849 { 2850 __asm__ __volatile__ ("vupkhpx 17, 14"); 2851 } 2852 2853 static void test_vupklsb (void) 2854 { 2855 __asm__ __volatile__ ("vupklsb 17, 14"); 2856 } 2857 2858 static void test_vupklsh (void) 2859 { 2860 __asm__ __volatile__ ("vupklsh 17, 14"); 2861 } 2862 2863 static void test_vupklpx (void) 2864 { 2865 __asm__ __volatile__ ("vupklpx 17, 14"); 2866 } 2867 2868 static test_t tests_al_ops_one[] = { 2869 { &test_vupkhsb , " vupkhsb", }, 2870 { &test_vupkhsh , " vupkhsh", }, 2871 { &test_vupkhpx , " vupkhpx", }, 2872 { &test_vupklsb , " vupklsb", }, 2873 { &test_vupklsh , " vupklsh", }, 2874 { &test_vupklpx , " vupklpx", }, 2875 { NULL, NULL, }, 2876 }; 2877 #endif /* defined (HAS_ALTIVEC) */ 2878 2879 #if defined (HAS_ALTIVEC) 2880 static void test_vcmpgtub (void) 2881 { 2882 __asm__ __volatile__ ("vcmpgtub 17, 14, 15"); 2883 } 2884 2885 static void test_vcmpgtuh (void) 2886 { 2887 __asm__ __volatile__ ("vcmpgtuh 17, 14, 15"); 2888 } 2889 2890 static void test_vcmpgtuw (void) 2891 { 2892 __asm__ __volatile__ ("vcmpgtuw 17, 14, 15"); 2893 } 2894 2895 static void test_vcmpgtsb (void) 2896 { 2897 __asm__ __volatile__ ("vcmpgtsb 17, 14, 15"); 2898 } 2899 2900 static void test_vcmpgtsh (void) 2901 { 2902 __asm__ __volatile__ ("vcmpgtsh 17, 14, 15"); 2903 } 2904 2905 static void test_vcmpgtsw (void) 2906 { 2907 __asm__ __volatile__ ("vcmpgtsw 17, 14, 15"); 2908 } 2909 2910 static void test_vcmpequb (void) 2911 { 2912 __asm__ __volatile__ ("vcmpequb 17, 14, 15"); 2913 } 2914 2915 static void test_vcmpequh (void) 2916 { 2917 __asm__ __volatile__ ("vcmpequh 17, 14, 15"); 2918 } 2919 2920 static void test_vcmpequw (void) 2921 { 2922 __asm__ __volatile__ ("vcmpequw 17, 14, 15"); 2923 } 2924 2925 static test_t tests_ac_ops_two[] = { 2926 { &test_vcmpgtub , " vcmpgtub", }, 2927 { &test_vcmpgtuh , " vcmpgtuh", }, 2928 { &test_vcmpgtuw , " vcmpgtuw", }, 2929 { &test_vcmpgtsb , " vcmpgtsb", }, 2930 { &test_vcmpgtsh , " vcmpgtsh", }, 2931 { &test_vcmpgtsw , " vcmpgtsw", }, 2932 { &test_vcmpequb , " vcmpequb", }, 2933 { &test_vcmpequh , " vcmpequh", }, 2934 { &test_vcmpequw , " vcmpequw", }, 2935 { NULL, NULL, }, 2936 }; 2937 #endif /* defined (HAS_ALTIVEC) */ 2938 2939 #if defined (HAS_ALTIVEC) 2940 static void test_vcmpgtub_ (void) 2941 { 2942 __asm__ __volatile__ ("vcmpgtub. 17, 14, 15"); 2943 } 2944 2945 static void test_vcmpgtuh_ (void) 2946 { 2947 __asm__ __volatile__ ("vcmpgtuh. 17, 14, 15"); 2948 } 2949 2950 static void test_vcmpgtuw_ (void) 2951 { 2952 __asm__ __volatile__ ("vcmpgtuw. 17, 14, 15"); 2953 } 2954 2955 static void test_vcmpgtsb_ (void) 2956 { 2957 __asm__ __volatile__ ("vcmpgtsb. 17, 14, 15"); 2958 } 2959 2960 static void test_vcmpgtsh_ (void) 2961 { 2962 __asm__ __volatile__ ("vcmpgtsh. 17, 14, 15"); 2963 } 2964 2965 static void test_vcmpgtsw_ (void) 2966 { 2967 __asm__ __volatile__ ("vcmpgtsw. 17, 14, 15"); 2968 } 2969 2970 static void test_vcmpequb_ (void) 2971 { 2972 __asm__ __volatile__ ("vcmpequb. 17, 14, 15"); 2973 } 2974 2975 static void test_vcmpequh_ (void) 2976 { 2977 __asm__ __volatile__ ("vcmpequh. 17, 14, 15"); 2978 } 2979 2980 static void test_vcmpequw_ (void) 2981 { 2982 __asm__ __volatile__ ("vcmpequw. 17, 14, 15"); 2983 } 2984 2985 static test_t tests_acr_ops_two[] = { 2986 { &test_vcmpgtub_ , " vcmpgtub.", }, 2987 { &test_vcmpgtuh_ , " vcmpgtuh.", }, 2988 { &test_vcmpgtuw_ , " vcmpgtuw.", }, 2989 { &test_vcmpgtsb_ , " vcmpgtsb.", }, 2990 { &test_vcmpgtsh_ , " vcmpgtsh.", }, 2991 { &test_vcmpgtsw_ , " vcmpgtsw.", }, 2992 { &test_vcmpequb_ , " vcmpequb.", }, 2993 { &test_vcmpequh_ , " vcmpequh.", }, 2994 { &test_vcmpequw_ , " vcmpequw.", }, 2995 { NULL, NULL, }, 2996 }; 2997 #endif /* defined (HAS_ALTIVEC) */ 2998 2999 #if defined (HAS_ALTIVEC) 3000 static void test_vsl (void) 3001 { 3002 __asm__ __volatile__ ("vsl 17, 14, 15"); 3003 } 3004 3005 static void test_vsr (void) 3006 { 3007 __asm__ __volatile__ ("vsr 17, 14, 15"); 3008 } 3009 3010 extern void test_vspltb (void); 3011 ASSEMBLY_FUNC("test_vspltb", "vspltb 17, 14, 0"); 3012 3013 extern void test_vsplth (void); 3014 ASSEMBLY_FUNC("test_vsplth", "vsplth 17, 14, 0"); 3015 3016 extern void test_vspltw (void); 3017 ASSEMBLY_FUNC("test_vspltw", "vspltw 17, 14, 0"); 3018 3019 extern void test_vspltisb (void); 3020 ASSEMBLY_FUNC("test_vspltisb", "vspltisb 17, 0"); 3021 3022 extern void test_vspltish (void); 3023 ASSEMBLY_FUNC("test_vspltish", "vspltish 17, 0"); 3024 3025 extern void test_vspltisw (void); 3026 ASSEMBLY_FUNC("test_vspltisw", "vspltisw 17, 0"); 3027 3028 extern void test_vsldoi (void); 3029 ASSEMBLY_FUNC("test_vsldoi", "vsldoi 17, 14, 15, 0"); 3030 3031 static void test_lvsl (void) 3032 { 3033 __asm__ __volatile__ ("lvsl 17, 14, 15"); 3034 } 3035 3036 static void test_lvsr (void) 3037 { 3038 __asm__ __volatile__ ("lvsr 17, 14, 15"); 3039 } 3040 3041 static test_t tests_av_int_ops_spe[] = { 3042 { &test_vsl , " vsl", }, 3043 { &test_vsr , " vsr", }, 3044 { &test_vspltb , " vspltb", }, 3045 { &test_vsplth , " vsplth", }, 3046 { &test_vspltw , " vspltw", }, 3047 { &test_vspltisb , " vspltisb", }, 3048 { &test_vspltish , " vspltish", }, 3049 { &test_vspltisw , " vspltisw", }, 3050 { &test_vsldoi , " vsldoi", }, 3051 { &test_lvsl , " lvsl", }, 3052 { &test_lvsr , " lvsr", }, 3053 { NULL, NULL, }, 3054 }; 3055 #endif /* defined (HAS_ALTIVEC) */ 3056 3057 #if defined (HAS_ALTIVEC) 3058 static void test_lvebx (void) 3059 { 3060 __asm__ __volatile__ ("lvebx 17,14,15"); 3061 } 3062 3063 static void test_lvehx (void) 3064 { 3065 __asm__ __volatile__ ("lvehx 17,14,15"); 3066 } 3067 3068 static void test_lvewx (void) 3069 { 3070 __asm__ __volatile__ ("lvewx 17,14,15"); 3071 } 3072 3073 static void test_lvx (void) 3074 { 3075 __asm__ __volatile__ ("lvx 17,14,15"); 3076 } 3077 3078 static void test_lvxl (void) 3079 { 3080 __asm__ __volatile__ ("lvxl 17,14,15"); 3081 } 3082 3083 static test_t tests_ald_ops_two[] = { 3084 { &test_lvebx , " lvebx", }, 3085 { &test_lvehx , " lvehx", }, 3086 { &test_lvewx , " lvewx", }, 3087 { &test_lvx , " lvx", }, 3088 { &test_lvxl , " lvxl", }, 3089 { NULL, NULL, }, 3090 }; 3091 #endif /* defined (HAS_ALTIVEC) */ 3092 3093 #if defined (HAS_ALTIVEC) 3094 static void test_stvebx (void) 3095 { 3096 __asm__ __volatile__ ("stvebx 14,15,16"); 3097 } 3098 3099 static void test_stvehx (void) 3100 { 3101 __asm__ __volatile__ ("stvehx 14,15,16"); 3102 } 3103 3104 static void test_stvewx (void) 3105 { 3106 __asm__ __volatile__ ("stvewx 14,15,16"); 3107 } 3108 3109 static void test_stvx (void) 3110 { 3111 __asm__ __volatile__ ("stvx 14,15,16"); 3112 } 3113 3114 static void test_stvxl (void) 3115 { 3116 __asm__ __volatile__ ("stvxl 14,15,16"); 3117 } 3118 3119 static test_t tests_ast_ops_three[] = { 3120 { &test_stvebx , " stvebx", }, 3121 { &test_stvehx , " stvehx", }, 3122 { &test_stvewx , " stvewx", }, 3123 { &test_stvx , " stvx", }, 3124 { &test_stvxl , " stvxl", }, 3125 { NULL, NULL, }, 3126 }; 3127 #endif /* defined (HAS_ALTIVEC) */ 3128 3129 #if defined (HAS_ALTIVEC) 3130 #if 1 3131 static void test_vmaddfp (void) 3132 { 3133 __asm__ __volatile__ ("vmaddfp 17, 14, 15, 16"); 3134 } 3135 3136 static void test_vnmsubfp (void) 3137 { 3138 __asm__ __volatile__ ("vnmsubfp 17, 14, 15, 16"); 3139 } 3140 #endif 3141 3142 static test_t tests_afa_ops_three[] = { 3143 { &test_vmaddfp , " vmaddfp", }, 3144 { &test_vnmsubfp , " vnmsubfp", }, 3145 { NULL, NULL, }, 3146 }; 3147 #endif /* defined (HAS_ALTIVEC) */ 3148 3149 #if defined (HAS_ALTIVEC) 3150 static void test_vaddfp (void) 3151 { 3152 __asm__ __volatile__ ("vaddfp 17, 14, 15"); 3153 } 3154 3155 static void test_vsubfp (void) 3156 { 3157 __asm__ __volatile__ ("vsubfp 17, 14, 15"); 3158 } 3159 3160 static void test_vmaxfp (void) 3161 { 3162 __asm__ __volatile__ ("vmaxfp 17, 14, 15"); 3163 } 3164 3165 static void test_vminfp (void) 3166 { 3167 __asm__ __volatile__ ("vminfp 17, 14, 15"); 3168 } 3169 3170 static test_t tests_afa_ops_two[] = { 3171 { &test_vaddfp , " vaddfp", }, 3172 { &test_vsubfp , " vsubfp", }, 3173 { &test_vmaxfp , " vmaxfp", }, 3174 { &test_vminfp , " vminfp", }, 3175 { NULL, NULL, }, 3176 }; 3177 #endif /* defined (HAS_ALTIVEC) */ 3178 3179 #if defined (HAS_ALTIVEC) 3180 static void test_vrfin (void) 3181 { 3182 __asm__ __volatile__ ("vrfin 17, 14"); 3183 } 3184 3185 static void test_vrfiz (void) 3186 { 3187 __asm__ __volatile__ ("vrfiz 17, 14"); 3188 } 3189 3190 static void test_vrfip (void) 3191 { 3192 __asm__ __volatile__ ("vrfip 17, 14"); 3193 } 3194 3195 static void test_vrfim (void) 3196 { 3197 __asm__ __volatile__ ("vrfim 17, 14"); 3198 } 3199 3200 static void test_vrefp (void) 3201 { 3202 __asm__ __volatile__ ("vrefp 17, 14"); 3203 } 3204 3205 static void test_vrsqrtefp (void) 3206 { 3207 __asm__ __volatile__ ("vrsqrtefp 17, 14"); 3208 } 3209 3210 #if 0 // TODO: Not yet supported 3211 static void test_vlogefp (void) 3212 { 3213 __asm__ __volatile__ ("vlogefp 17, 14"); 3214 } 3215 3216 static void test_vexptefp (void) 3217 { 3218 __asm__ __volatile__ ("vexptefp 17, 14"); 3219 } 3220 #endif 3221 3222 static test_t tests_afa_ops_one[] = { 3223 { &test_vrfin , " vrfin", }, 3224 { &test_vrfiz , " vrfiz", }, 3225 { &test_vrfip , " vrfip", }, 3226 { &test_vrfim , " vrfim", }, 3227 { &test_vrefp , " vrefp", }, 3228 { &test_vrsqrtefp , " vrsqrtefp", }, 3229 // { &test_vlogefp , " vlogefp", }, // TODO: Not yet supported 3230 // { &test_vexptefp , " vexptefp", }, // TODO: Not yet supported 3231 { NULL, NULL, }, 3232 }; 3233 #endif /* defined (HAS_ALTIVEC) */ 3234 3235 #if defined (HAS_ALTIVEC) 3236 static void test_vcmpgtfp (void) 3237 { 3238 __asm__ __volatile__ ("vcmpgtfp 17, 14, 15"); 3239 } 3240 3241 static void test_vcmpeqfp (void) 3242 { 3243 __asm__ __volatile__ ("vcmpeqfp 17, 14, 15"); 3244 } 3245 3246 static void test_vcmpgefp (void) 3247 { 3248 __asm__ __volatile__ ("vcmpgefp 17, 14, 15"); 3249 } 3250 3251 static void test_vcmpbfp (void) 3252 { 3253 __asm__ __volatile__ ("vcmpbfp 17, 14, 15"); 3254 } 3255 3256 static test_t tests_afc_ops_two[] = { 3257 { &test_vcmpgtfp , " vcmpgtfp", }, 3258 { &test_vcmpeqfp , " vcmpeqfp", }, 3259 { &test_vcmpgefp , " vcmpgefp", }, 3260 { &test_vcmpbfp , " vcmpbfp", }, 3261 { NULL, NULL, }, 3262 }; 3263 #endif /* defined (HAS_ALTIVEC) */ 3264 3265 #if defined (HAS_ALTIVEC) 3266 static void test_vcmpgtfp_ (void) 3267 { 3268 __asm__ __volatile__ ("vcmpgtfp. 17, 14, 15"); 3269 } 3270 3271 static void test_vcmpeqfp_ (void) 3272 { 3273 __asm__ __volatile__ ("vcmpeqfp. 17, 14, 15"); 3274 } 3275 3276 static void test_vcmpgefp_ (void) 3277 { 3278 __asm__ __volatile__ ("vcmpgefp. 17, 14, 15"); 3279 } 3280 3281 static void test_vcmpbfp_ (void) 3282 { 3283 __asm__ __volatile__ ("vcmpbfp. 17, 14, 15"); 3284 } 3285 3286 static test_t tests_afcr_ops_two[] = { 3287 { &test_vcmpgtfp_ , " vcmpgtfp.", }, 3288 { &test_vcmpeqfp_ , " vcmpeqfp.", }, 3289 { &test_vcmpgefp_ , " vcmpgefp.", }, 3290 { &test_vcmpbfp_ , " vcmpbfp.", }, 3291 { NULL, NULL, }, 3292 }; 3293 #endif /* defined (HAS_ALTIVEC) */ 3294 3295 #if defined (HAS_ALTIVEC) 3296 extern void test_vcfux (void); 3297 ASSEMBLY_FUNC("test_vcfux", "vcfux 17, 14, 0"); 3298 3299 extern void test_vcfsx (void); 3300 ASSEMBLY_FUNC("test_vcfsx", "vcfsx 17, 14, 0"); 3301 3302 extern void test_vctuxs (void); 3303 ASSEMBLY_FUNC("test_vctuxs", "vctuxs 17, 14, 0"); 3304 3305 extern void test_vctsxs (void); 3306 ASSEMBLY_FUNC("test_vctsxs", "vctsxs 17, 14, 0"); 3307 3308 static test_t tests_av_float_ops_spe[] = { 3309 { &test_vcfux , " vcfux", }, 3310 { &test_vcfsx , " vcfsx", }, 3311 { &test_vctuxs , " vctuxs", }, 3312 { &test_vctsxs , " vctsxs", }, 3313 { NULL, NULL, }, 3314 }; 3315 #endif /* defined (HAS_ALTIVEC) */ 3316 3317 #if defined (IS_PPC405) 3318 static void test_macchw (void) 3319 { 3320 __asm__ __volatile__ ("macchw 17, 14, 15"); 3321 } 3322 3323 static void test_macchwo (void) 3324 { 3325 __asm__ __volatile__ ("macchwo 17, 14, 15"); 3326 } 3327 3328 static void test_macchws (void) 3329 { 3330 __asm__ __volatile__ ("macchws 17, 14, 15"); 3331 } 3332 3333 static void test_macchwso (void) 3334 { 3335 __asm__ __volatile__ ("macchwso 17, 14, 15"); 3336 } 3337 3338 static void test_macchwsu (void) 3339 { 3340 __asm__ __volatile__ ("macchwsu 17, 14, 15"); 3341 } 3342 3343 static void test_macchwsuo (void) 3344 { 3345 __asm__ __volatile__ ("macchwsuo 17, 14, 15"); 3346 } 3347 3348 static void test_macchwu (void) 3349 { 3350 __asm__ __volatile__ ("macchwu 17, 14, 15"); 3351 } 3352 3353 static void test_macchwuo (void) 3354 { 3355 __asm__ __volatile__ ("macchwuo 17, 14, 15"); 3356 } 3357 3358 static void test_machhw (void) 3359 { 3360 __asm__ __volatile__ ("machhw 17, 14, 15"); 3361 } 3362 3363 static void test_machhwo (void) 3364 { 3365 __asm__ __volatile__ ("machhwo 17, 14, 15"); 3366 } 3367 3368 static void test_machhws (void) 3369 { 3370 __asm__ __volatile__ ("machhws 17, 14, 15"); 3371 } 3372 3373 static void test_machhwso (void) 3374 { 3375 __asm__ __volatile__ ("machhwso 17, 14, 15"); 3376 } 3377 3378 static void test_machhwsu (void) 3379 { 3380 __asm__ __volatile__ ("machhwsu 17, 14, 15"); 3381 } 3382 3383 static void test_machhwsuo (void) 3384 { 3385 __asm__ __volatile__ ("machhwsuo 17, 14, 15"); 3386 } 3387 3388 static void test_machhwu (void) 3389 { 3390 __asm__ __volatile__ ("machhwu 17, 14, 15"); 3391 } 3392 3393 static void test_machhwuo (void) 3394 { 3395 __asm__ __volatile__ ("machhwuo 17, 14, 15"); 3396 } 3397 3398 static void test_maclhw (void) 3399 { 3400 __asm__ __volatile__ ("maclhw 17, 14, 15"); 3401 } 3402 3403 static void test_maclhwo (void) 3404 { 3405 __asm__ __volatile__ ("maclhwo 17, 14, 15"); 3406 } 3407 3408 static void test_maclhws (void) 3409 { 3410 __asm__ __volatile__ ("maclhws 17, 14, 15"); 3411 } 3412 3413 static void test_maclhwso (void) 3414 { 3415 __asm__ __volatile__ ("maclhwso 17, 14, 15"); 3416 } 3417 3418 static void test_maclhwsu (void) 3419 { 3420 __asm__ __volatile__ ("maclhwsu 17, 14, 15"); 3421 } 3422 3423 static void test_maclhwsuo (void) 3424 { 3425 __asm__ __volatile__ ("maclhwsuo 17, 14, 15"); 3426 } 3427 3428 static void test_maclhwu (void) 3429 { 3430 __asm__ __volatile__ ("maclhwu 17, 14, 15"); 3431 } 3432 3433 static void test_maclhwuo (void) 3434 { 3435 __asm__ __volatile__ ("maclhwuo 17, 14, 15"); 3436 } 3437 3438 static void test_mulchw (void) 3439 { 3440 __asm__ __volatile__ ("mulchw 17, 14, 15"); 3441 } 3442 3443 static void test_mulchwu (void) 3444 { 3445 __asm__ __volatile__ ("mulchwu 17, 14, 15"); 3446 } 3447 3448 static void test_mulhhw (void) 3449 { 3450 __asm__ __volatile__ ("mulhhw 17, 14, 15"); 3451 } 3452 3453 static void test_mulhhwu (void) 3454 { 3455 __asm__ __volatile__ ("mulhhwu 17, 14, 15"); 3456 } 3457 3458 static void test_mullhw (void) 3459 { 3460 __asm__ __volatile__ ("mullhw 17, 14, 15"); 3461 } 3462 3463 static void test_mullhwu (void) 3464 { 3465 __asm__ __volatile__ ("mullhwu 17, 14, 15"); 3466 } 3467 3468 static void test_nmacchw (void) 3469 { 3470 __asm__ __volatile__ ("nmacchw 17, 14, 15"); 3471 } 3472 3473 static void test_nmacchwo (void) 3474 { 3475 __asm__ __volatile__ ("nmacchwo 17, 14, 15"); 3476 } 3477 3478 static void test_nmacchws (void) 3479 { 3480 __asm__ __volatile__ ("nmacchws 17, 14, 15"); 3481 } 3482 3483 static void test_nmacchwso (void) 3484 { 3485 __asm__ __volatile__ ("nmacchwso 17, 14, 15"); 3486 } 3487 3488 static void test_nmachhw (void) 3489 { 3490 __asm__ __volatile__ ("nmachhw 17, 14, 15"); 3491 } 3492 3493 static void test_nmachhwo (void) 3494 { 3495 __asm__ __volatile__ ("nmachhwo 17, 14, 15"); 3496 } 3497 3498 static void test_nmachhws (void) 3499 { 3500 __asm__ __volatile__ ("nmachhws 17, 14, 15"); 3501 } 3502 3503 static void test_nmachhwso (void) 3504 { 3505 __asm__ __volatile__ ("nmachhwso 17, 14, 15"); 3506 } 3507 3508 static void test_nmaclhw (void) 3509 { 3510 __asm__ __volatile__ ("nmaclhw 17, 14, 15"); 3511 } 3512 3513 static void test_nmaclhwo (void) 3514 { 3515 __asm__ __volatile__ ("nmaclhwo 17, 14, 15"); 3516 } 3517 3518 static void test_nmaclhws (void) 3519 { 3520 __asm__ __volatile__ ("nmaclhws 17, 14, 15"); 3521 } 3522 3523 static void test_nmaclhwso (void) 3524 { 3525 __asm__ __volatile__ ("nmaclhwso 17, 14, 15"); 3526 } 3527 3528 static test_t tests_p4m_ops_two[] = { 3529 { &test_macchw , " macchw", }, 3530 { &test_macchwo , " macchwo", }, 3531 { &test_macchws , " macchws", }, 3532 { &test_macchwso , " macchwso", }, 3533 { &test_macchwsu , " macchwsu", }, 3534 { &test_macchwsuo , " macchwsuo", }, 3535 { &test_macchwu , " macchwu", }, 3536 { &test_macchwuo , " macchwuo", }, 3537 { &test_machhw , " machhw", }, 3538 { &test_machhwo , " machhwo", }, 3539 { &test_machhws , " machhws", }, 3540 { &test_machhwso , " machhwso", }, 3541 { &test_machhwsu , " machhwsu", }, 3542 { &test_machhwsuo , " machhwsuo", }, 3543 { &test_machhwu , " machhwu", }, 3544 { &test_machhwuo , " machhwuo", }, 3545 { &test_maclhw , " maclhw", }, 3546 { &test_maclhwo , " maclhwo", }, 3547 { &test_maclhws , " maclhws", }, 3548 { &test_maclhwso , " maclhwso", }, 3549 { &test_maclhwsu , " maclhwsu", }, 3550 { &test_maclhwsuo , " maclhwsuo", }, 3551 { &test_maclhwu , " maclhwu", }, 3552 { &test_maclhwuo , " maclhwuo", }, 3553 { &test_mulchw , " mulchw", }, 3554 { &test_mulchwu , " mulchwu", }, 3555 { &test_mulhhw , " mulhhw", }, 3556 { &test_mulhhwu , " mulhhwu", }, 3557 { &test_mullhw , " mullhw", }, 3558 { &test_mullhwu , " mullhwu", }, 3559 { &test_nmacchw , " nmacchw", }, 3560 { &test_nmacchwo , " nmacchwo", }, 3561 { &test_nmacchws , " nmacchws", }, 3562 { &test_nmacchwso , " nmacchwso", }, 3563 { &test_nmachhw , " nmachhw", }, 3564 { &test_nmachhwo , " nmachhwo", }, 3565 { &test_nmachhws , " nmachhws", }, 3566 { &test_nmachhwso , " nmachhwso", }, 3567 { &test_nmaclhw , " nmaclhw", }, 3568 { &test_nmaclhwo , " nmaclhwo", }, 3569 { &test_nmaclhws , " nmaclhws", }, 3570 { &test_nmaclhwso , " nmaclhwso", }, 3571 { NULL, NULL, }, 3572 }; 3573 #endif /* defined (IS_PPC405) */ 3574 3575 #if defined (IS_PPC405) 3576 static void test_macchw_ (void) 3577 { 3578 __asm__ __volatile__ ("macchw. 17, 14, 15"); 3579 } 3580 3581 static void test_macchwo_ (void) 3582 { 3583 __asm__ __volatile__ ("macchwo. 17, 14, 15"); 3584 } 3585 3586 static void test_macchws_ (void) 3587 { 3588 __asm__ __volatile__ ("macchws. 17, 14, 15"); 3589 } 3590 3591 static void test_macchwso_ (void) 3592 { 3593 __asm__ __volatile__ ("macchwso. 17, 14, 15"); 3594 } 3595 3596 static void test_macchwsu_ (void) 3597 { 3598 __asm__ __volatile__ ("macchwsu. 17, 14, 15"); 3599 } 3600 3601 static void test_macchwsuo_ (void) 3602 { 3603 __asm__ __volatile__ ("macchwsuo. 17, 14, 15"); 3604 } 3605 3606 static void test_macchwu_ (void) 3607 { 3608 __asm__ __volatile__ ("macchwu. 17, 14, 15"); 3609 } 3610 3611 static void test_macchwuo_ (void) 3612 { 3613 __asm__ __volatile__ ("macchwuo. 17, 14, 15"); 3614 } 3615 3616 static void test_machhw_ (void) 3617 { 3618 __asm__ __volatile__ ("machhw. 17, 14, 15"); 3619 } 3620 3621 static void test_machhwo_ (void) 3622 { 3623 __asm__ __volatile__ ("machhwo. 17, 14, 15"); 3624 } 3625 3626 static void test_machhws_ (void) 3627 { 3628 __asm__ __volatile__ ("machhws. 17, 14, 15"); 3629 } 3630 3631 static void test_machhwso_ (void) 3632 { 3633 __asm__ __volatile__ ("machhwso. 17, 14, 15"); 3634 } 3635 3636 static void test_machhwsu_ (void) 3637 { 3638 __asm__ __volatile__ ("machhwsu. 17, 14, 15"); 3639 } 3640 3641 static void test_machhwsuo_ (void) 3642 { 3643 __asm__ __volatile__ ("machhwsuo. 17, 14, 15"); 3644 } 3645 3646 static void test_machhwu_ (void) 3647 { 3648 __asm__ __volatile__ ("machhwu. 17, 14, 15"); 3649 } 3650 3651 static void test_machhwuo_ (void) 3652 { 3653 __asm__ __volatile__ ("machhwuo. 17, 14, 15"); 3654 } 3655 3656 static void test_maclhw_ (void) 3657 { 3658 __asm__ __volatile__ ("maclhw. 17, 14, 15"); 3659 } 3660 3661 static void test_maclhwo_ (void) 3662 { 3663 __asm__ __volatile__ ("maclhwo. 17, 14, 15"); 3664 } 3665 3666 static void test_maclhws_ (void) 3667 { 3668 __asm__ __volatile__ ("maclhws. 17, 14, 15"); 3669 } 3670 3671 static void test_maclhwso_ (void) 3672 { 3673 __asm__ __volatile__ ("maclhwso. 17, 14, 15"); 3674 } 3675 3676 static void test_maclhwsu_ (void) 3677 { 3678 __asm__ __volatile__ ("maclhwsu. 17, 14, 15"); 3679 } 3680 3681 static void test_maclhwsuo_ (void) 3682 { 3683 __asm__ __volatile__ ("maclhwsuo. 17, 14, 15"); 3684 } 3685 3686 static void test_maclhwu_ (void) 3687 { 3688 __asm__ __volatile__ ("maclhwu. 17, 14, 15"); 3689 } 3690 3691 static void test_maclhwuo_ (void) 3692 { 3693 __asm__ __volatile__ ("maclhwuo. 17, 14, 15"); 3694 } 3695 3696 static void test_mulchw_ (void) 3697 { 3698 __asm__ __volatile__ ("mulchw. 17, 14, 15"); 3699 } 3700 3701 static void test_mulchwu_ (void) 3702 { 3703 __asm__ __volatile__ ("mulchwu. 17, 14, 15"); 3704 } 3705 3706 static void test_mulhhw_ (void) 3707 { 3708 __asm__ __volatile__ ("mulhhw. 17, 14, 15"); 3709 } 3710 3711 static void test_mulhhwu_ (void) 3712 { 3713 __asm__ __volatile__ ("mulhhwu. 17, 14, 15"); 3714 } 3715 3716 static void test_mullhw_ (void) 3717 { 3718 __asm__ __volatile__ ("mullhw. 17, 14, 15"); 3719 } 3720 3721 static void test_mullhwu_ (void) 3722 { 3723 __asm__ __volatile__ ("mullhwu. 17, 14, 15"); 3724 } 3725 3726 static void test_nmacchw_ (void) 3727 { 3728 __asm__ __volatile__ ("nmacchw. 17, 14, 15"); 3729 } 3730 3731 static void test_nmacchwo_ (void) 3732 { 3733 __asm__ __volatile__ ("nmacchwo. 17, 14, 15"); 3734 } 3735 3736 static void test_nmacchws_ (void) 3737 { 3738 __asm__ __volatile__ ("nmacchws. 17, 14, 15"); 3739 } 3740 3741 static void test_nmacchwso_ (void) 3742 { 3743 __asm__ __volatile__ ("nmacchwso. 17, 14, 15"); 3744 } 3745 3746 static void test_nmachhw_ (void) 3747 { 3748 __asm__ __volatile__ ("nmachhw. 17, 14, 15"); 3749 } 3750 3751 static void test_nmachhwo_ (void) 3752 { 3753 __asm__ __volatile__ ("nmachhwo. 17, 14, 15"); 3754 } 3755 3756 static void test_nmachhws_ (void) 3757 { 3758 __asm__ __volatile__ ("nmachhws. 17, 14, 15"); 3759 } 3760 3761 static void test_nmachhwso_ (void) 3762 { 3763 __asm__ __volatile__ ("nmachhwso. 17, 14, 15"); 3764 } 3765 3766 static void test_nmaclhw_ (void) 3767 { 3768 __asm__ __volatile__ ("nmaclhw. 17, 14, 15"); 3769 } 3770 3771 static void test_nmaclhwo_ (void) 3772 { 3773 __asm__ __volatile__ ("nmaclhwo. 17, 14, 15"); 3774 } 3775 3776 static void test_nmaclhws_ (void) 3777 { 3778 __asm__ __volatile__ ("nmaclhws. 17, 14, 15"); 3779 } 3780 3781 static void test_nmaclhwso_ (void) 3782 { 3783 __asm__ __volatile__ ("nmaclhwso. 17, 14, 15"); 3784 } 3785 3786 static test_t tests_p4mc_ops_two[] = { 3787 { &test_macchw_ , " macchw.", }, 3788 { &test_macchwo_ , " macchwo.", }, 3789 { &test_macchws_ , " macchws.", }, 3790 { &test_macchwso_ , " macchwso.", }, 3791 { &test_macchwsu_ , " macchwsu.", }, 3792 { &test_macchwsuo_ , " macchwsuo.", }, 3793 { &test_macchwu_ , " macchwu.", }, 3794 { &test_macchwuo_ , " macchwuo.", }, 3795 { &test_machhw_ , " machhw.", }, 3796 { &test_machhwo_ , " machhwo.", }, 3797 { &test_machhws_ , " machhws.", }, 3798 { &test_machhwso_ , " machhwso.", }, 3799 { &test_machhwsu_ , " machhwsu.", }, 3800 { &test_machhwsuo_ , " machhwsuo.", }, 3801 { &test_machhwu_ , " machhwu.", }, 3802 { &test_machhwuo_ , " machhwuo.", }, 3803 { &test_maclhw_ , " maclhw.", }, 3804 { &test_maclhwo_ , " maclhwo.", }, 3805 { &test_maclhws_ , " maclhws.", }, 3806 { &test_maclhwso_ , " maclhwso.", }, 3807 { &test_maclhwsu_ , " maclhwsu.", }, 3808 { &test_maclhwsuo_ , " maclhwsuo.", }, 3809 { &test_maclhwu_ , " maclhwu.", }, 3810 { &test_maclhwuo_ , " maclhwuo.", }, 3811 { &test_mulchw_ , " mulchw.", }, 3812 { &test_mulchwu_ , " mulchwu.", }, 3813 { &test_mulhhw_ , " mulhhw.", }, 3814 { &test_mulhhwu_ , " mulhhwu.", }, 3815 { &test_mullhw_ , " mullhw.", }, 3816 { &test_mullhwu_ , " mullhwu.", }, 3817 { &test_nmacchw_ , " nmacchw.", }, 3818 { &test_nmacchwo_ , " nmacchwo.", }, 3819 { &test_nmacchws_ , " nmacchws.", }, 3820 { &test_nmacchwso_ , " nmacchwso.", }, 3821 { &test_nmachhw_ , " nmachhw.", }, 3822 { &test_nmachhwo_ , " nmachhwo.", }, 3823 { &test_nmachhws_ , " nmachhws.", }, 3824 { &test_nmachhwso_ , " nmachhwso.", }, 3825 { &test_nmaclhw_ , " nmaclhw.", }, 3826 { &test_nmaclhwo_ , " nmaclhwo.", }, 3827 { &test_nmaclhws_ , " nmaclhws.", }, 3828 { &test_nmaclhwso_ , " nmaclhwso.", }, 3829 { NULL, NULL, }, 3830 }; 3831 #endif /* defined (IS_PPC405) */ 3832 3833 static test_table_t all_tests[] = { 3834 { 3835 tests_ia_ops_two , 3836 "PPC integer arith insns with two args", 3837 0x00010102, 3838 }, 3839 { 3840 tests_iar_ops_two , 3841 "PPC integer arith insns with two args with flags update", 3842 0x01010102, 3843 }, 3844 { 3845 tests_iac_ops_two , 3846 "PPC integer arith insns with two args and carry", 3847 0x02010102, 3848 }, 3849 { 3850 tests_iacr_ops_two , 3851 "PPC integer arith insns with two args and carry with flags update", 3852 0x03010102, 3853 }, 3854 { 3855 tests_il_ops_two , 3856 "PPC integer logical insns with two args", 3857 0x00010202, 3858 }, 3859 { 3860 tests_ilr_ops_two , 3861 "PPC integer logical insns with two args with flags update", 3862 0x01010202, 3863 }, 3864 { 3865 tests_icr_ops_two , 3866 "PPC integer compare insns (two args)", 3867 0x01010304, 3868 }, 3869 { 3870 tests_icr_ops_two_i16 , 3871 "PPC integer compare with immediate insns (two args)", 3872 0x01010305, 3873 }, 3874 { 3875 tests_ia_ops_two_i16 , 3876 "PPC integer arith insns\n with one register + one 16 bits immediate args", 3877 0x00010106, 3878 }, 3879 { 3880 tests_iar_ops_two_i16 , 3881 "PPC integer arith insns\n with one register + one 16 bits immediate args with flags update", 3882 0x01010106, 3883 }, 3884 { 3885 tests_il_ops_two_i16 , 3886 "PPC integer logical insns\n with one register + one 16 bits immediate args", 3887 0x00010206, 3888 }, 3889 { 3890 tests_ilr_ops_two_i16 , 3891 "PPC integer logical insns\n with one register + one 16 bits immediate args with flags update", 3892 0x01010206, 3893 }, 3894 { 3895 tests_crl_ops_two , 3896 "PPC condition register logical insns - two operands", 3897 0x01010202, 3898 }, 3899 { 3900 tests_iac_ops_one , 3901 "PPC integer arith insns with one arg and carry", 3902 0x02010101, 3903 }, 3904 { 3905 tests_iacr_ops_one , 3906 "PPC integer arith insns with one arg and carry with flags update", 3907 0x03010101, 3908 }, 3909 { 3910 tests_il_ops_one , 3911 "PPC integer logical insns with one arg", 3912 0x00010201, 3913 }, 3914 { 3915 tests_ilr_ops_one , 3916 "PPC integer logical insns with one arg with flags update", 3917 0x01010201, 3918 }, 3919 { 3920 tests_il_ops_spe , 3921 "PPC logical insns with special forms", 3922 0x00010207, 3923 }, 3924 { 3925 tests_ilr_ops_spe , 3926 "PPC logical insns with special forms with flags update", 3927 0x01010207, 3928 }, 3929 { 3930 tests_ild_ops_two_i16 , 3931 "PPC integer load insns\n with one register + one 16 bits immediate args with flags update", 3932 0x00010508, 3933 }, 3934 { 3935 tests_ild_ops_two , 3936 "PPC integer load insns with two register args", 3937 0x00010509, 3938 }, 3939 { 3940 tests_ist_ops_three_i16, 3941 "PPC integer store insns\n with one register + one 16 bits immediate args with flags update", 3942 0x0001050a, 3943 }, 3944 { 3945 tests_ist_ops_three , 3946 "PPC integer store insns with three register args", 3947 0x0001050b, 3948 }, 3949 { 3950 tests_popcnt_ops_one , 3951 "PPC integer population count with one register args, no flags", 3952 0x00010601, 3953 }, 3954 #if !defined (NO_FLOAT) 3955 { 3956 tests_fa_ops_three , 3957 "PPC floating point arith insns with three args", 3958 0x00020103, 3959 }, 3960 #endif /* !defined (NO_FLOAT) */ 3961 #if !defined (NO_FLOAT) 3962 { 3963 tests_far_ops_three , 3964 "PPC floating point arith insns\n with three args with flags update", 3965 0x01020103, 3966 }, 3967 #endif /* !defined (NO_FLOAT) */ 3968 #if !defined (NO_FLOAT) 3969 { 3970 tests_fa_ops_two , 3971 "PPC floating point arith insns with two args", 3972 0x00020102, 3973 }, 3974 #endif /* !defined (NO_FLOAT) */ 3975 #if !defined (NO_FLOAT) 3976 { 3977 tests_far_ops_two , 3978 "PPC floating point arith insns\n with two args with flags update", 3979 0x01020102, 3980 }, 3981 #endif /* !defined (NO_FLOAT) */ 3982 #if !defined (NO_FLOAT) 3983 { 3984 tests_fcr_ops_two , 3985 "PPC floating point compare insns (two args)", 3986 0x01020304, 3987 }, 3988 #endif /* !defined (NO_FLOAT) */ 3989 #if !defined (NO_FLOAT) 3990 { 3991 tests_fa_ops_one , 3992 "PPC floating point arith insns with one arg", 3993 0x00020101, 3994 }, 3995 #endif /* !defined (NO_FLOAT) */ 3996 #if !defined (NO_FLOAT) 3997 { 3998 tests_far_ops_one , 3999 "PPC floating point arith insns\n with one arg with flags update", 4000 0x01020101, 4001 }, 4002 #endif /* !defined (NO_FLOAT) */ 4003 #if !defined (NO_FLOAT) 4004 { 4005 tests_fl_ops_spe , 4006 "PPC floating point status register manipulation insns", 4007 0x00020207, 4008 }, 4009 #endif /* !defined (NO_FLOAT) */ 4010 #if !defined (NO_FLOAT) 4011 { 4012 tests_flr_ops_spe , 4013 "PPC floating point status register manipulation insns\n with flags update", 4014 0x01020207, 4015 }, 4016 #endif /* !defined (NO_FLOAT) */ 4017 #if !defined (NO_FLOAT) 4018 { 4019 tests_fld_ops_two_i16 , 4020 "PPC float load insns\n with one register + one 16 bits immediate args with flags update", 4021 0x00020508, 4022 }, 4023 #endif /* !defined (NO_FLOAT) */ 4024 #if !defined (NO_FLOAT) 4025 { 4026 tests_fld_ops_two , 4027 "PPC float load insns with two register args", 4028 0x00020509, 4029 }, 4030 #endif /* !defined (NO_FLOAT) */ 4031 #if !defined (NO_FLOAT) 4032 { 4033 tests_fst_ops_three_i16, 4034 "PPC float store insns\n with one register + one 16 bits immediate args with flags update", 4035 0x0002050a, 4036 }, 4037 #endif /* !defined (NO_FLOAT) */ 4038 #if !defined (NO_FLOAT) 4039 { 4040 tests_fst_ops_three , 4041 "PPC float store insns with three register args", 4042 0x0002050b, 4043 }, 4044 #endif /* !defined (NO_FLOAT) */ 4045 #if defined (HAS_ALTIVEC) 4046 { 4047 tests_aa_ops_three , 4048 "PPC altivec integer arith insns with three args", 4049 0x00040103, 4050 }, 4051 #endif /* defined (HAS_ALTIVEC) */ 4052 #if defined (HAS_ALTIVEC) 4053 { 4054 tests_al_ops_three , 4055 "PPC altivec integer logical insns with three args", 4056 0x00040203, 4057 }, 4058 #endif /* defined (HAS_ALTIVEC) */ 4059 #if defined (HAS_ALTIVEC) 4060 { 4061 tests_aa_ops_two , 4062 "PPC altivec integer arith insns with two args", 4063 0x00040102, 4064 }, 4065 #endif /* defined (HAS_ALTIVEC) */ 4066 #if defined (HAS_ALTIVEC) 4067 { 4068 tests_al_ops_two , 4069 "PPC altivec integer logical insns with two args", 4070 0x00040202, 4071 }, 4072 #endif /* defined (HAS_ALTIVEC) */ 4073 #if defined (HAS_ALTIVEC) 4074 { 4075 tests_al_ops_one , 4076 "PPC altivec integer logical insns with one arg", 4077 0x00040201, 4078 }, 4079 #endif /* defined (HAS_ALTIVEC) */ 4080 #if defined (HAS_ALTIVEC) 4081 { 4082 tests_ac_ops_two , 4083 "Altivec integer compare insns", 4084 0x00040302, 4085 }, 4086 #endif /* defined (HAS_ALTIVEC) */ 4087 #if defined (HAS_ALTIVEC) 4088 { 4089 tests_acr_ops_two , 4090 "Altivec integer compare insns with flags update", 4091 0x01040302, 4092 }, 4093 #endif /* defined (HAS_ALTIVEC) */ 4094 #if defined (HAS_ALTIVEC) 4095 { 4096 tests_av_int_ops_spe , 4097 "Altivec integer special insns", 4098 0x00040207, 4099 }, 4100 #endif /* defined (HAS_ALTIVEC) */ 4101 #if defined (HAS_ALTIVEC) 4102 { 4103 tests_ald_ops_two , 4104 "Altivec load insns with two register args", 4105 0x00040509, 4106 }, 4107 #endif /* defined (HAS_ALTIVEC) */ 4108 #if defined (HAS_ALTIVEC) 4109 { 4110 tests_ast_ops_three , 4111 "Altivec store insns with three register args", 4112 0x0004050b, 4113 }, 4114 #endif /* defined (HAS_ALTIVEC) */ 4115 #if defined (HAS_ALTIVEC) 4116 { 4117 tests_afa_ops_two , 4118 "Altivec floating point arith insns with two args", 4119 0x00050102, 4120 }, 4121 #endif /* defined (HAS_ALTIVEC) */ 4122 #if defined (HAS_ALTIVEC) 4123 { 4124 tests_afa_ops_three , 4125 "Altivec floating point arith insns with three args", 4126 0x00050103, 4127 }, 4128 #endif /* defined (HAS_ALTIVEC) */ 4129 #if defined (HAS_ALTIVEC) 4130 { 4131 tests_afa_ops_one , 4132 "Altivec floating point arith insns with one arg", 4133 0x00050101, 4134 }, 4135 #endif /* defined (HAS_ALTIVEC) */ 4136 #if defined (HAS_ALTIVEC) 4137 { 4138 tests_afc_ops_two , 4139 "Altivec floating point compare insns", 4140 0x00050302, 4141 }, 4142 #endif /* defined (HAS_ALTIVEC) */ 4143 #if defined (HAS_ALTIVEC) 4144 { 4145 tests_afcr_ops_two , 4146 "Altivec floating point compare insns with flags update", 4147 0x01050302, 4148 }, 4149 #endif /* defined (HAS_ALTIVEC) */ 4150 #if defined (HAS_ALTIVEC) 4151 { 4152 tests_av_float_ops_spe, 4153 "Altivec float special insns", 4154 0x00050207, 4155 }, 4156 #endif /* defined (HAS_ALTIVEC) */ 4157 #if defined (IS_PPC405) 4158 { 4159 tests_p4m_ops_two , 4160 "PPC 405 mac insns with three args", 4161 0x00030102, 4162 }, 4163 #endif /* defined (IS_PPC405) */ 4164 #if defined (IS_PPC405) 4165 { 4166 tests_p4mc_ops_two , 4167 "PPC 405 mac insns with three args with flags update", 4168 0x01030102, 4169 }, 4170 #endif /* defined (IS_PPC405) */ 4171 { NULL, NULL, 0x00000000, }, 4172 }; 4173 4174 /* -------------- END #include "ops-ppc.c" -------------- */ 4175 4176 static int verbose = 0; 4177 static int arg_list_size = 0; 4178 4179 static double *fargs = NULL; 4180 static int nb_fargs = 0; 4181 static int nb_normal_fargs = 0; 4182 static HWord_t *iargs = NULL; 4183 static int nb_iargs = 0; 4184 static uint16_t *ii16 = NULL; 4185 static int nb_ii16 = 0; 4186 4187 #if defined (HAS_ALTIVEC) 4188 static vector unsigned int* viargs = NULL; 4189 static int nb_viargs = 0; 4190 static vector float* vfargs = NULL; 4191 static int nb_vfargs = 0; 4192 4193 //#define TEST_VSCR_SAT 4194 #endif 4195 4196 static inline void register_farg (void *farg, 4197 int s, uint16_t _exp, uint64_t mant) 4198 { 4199 uint64_t tmp; 4200 4201 tmp = ((uint64_t)s << 63) | ((uint64_t)_exp << 52) | mant; 4202 *(uint64_t *)farg = tmp; 4203 #ifndef __powerpc64__ 4204 AB_DPRINTF("%d %03x %013llx => %016llx %0e\n", 4205 #else 4206 AB_DPRINTF("%d %03x %013lx => %016lx %0e\n", 4207 #endif 4208 s, _exp, mant, *(uint64_t *)farg, *(double *)farg); 4209 } 4210 4211 static void build_fargs_table (void) 4212 { 4213 /* Double precision: 4214 * Sign goes from zero to one (1 bit) 4215 * Exponent goes from 0 to ((1 << 12) - 1) (11 bits) 4216 * Mantissa goes from 1 to ((1 << 52) - 1) (52 bits) 4217 * + special values: 4218 * +0.0 : 0 0x000 0x0000000000000 => 0x0000000000000000 4219 * -0.0 : 1 0x000 0x0000000000000 => 0x8000000000000000 4220 * +infinity : 0 0x7FF 0x0000000000000 => 0x7FF0000000000000 4221 * -infinity : 1 0x7FF 0x0000000000000 => 0xFFF0000000000000 4222 * +QNaN : 0 0x7FF 0x7FFFFFFFFFFFF => 0x7FF7FFFFFFFFFFFF 4223 * -QNaN : 1 0x7FF 0x7FFFFFFFFFFFF => 0xFFF7FFFFFFFFFFFF 4224 * +SNaN : 0 0x7FF 0x8000000000000 => 0x7FF8000000000000 4225 * -SNaN : 1 0x7FF 0x8000000000000 => 0xFFF8000000000000 4226 * (8 values) 4227 4228 * Ref only: 4229 * Single precision 4230 * Sign: 1 bit 4231 * Exponent: 8 bits 4232 * Mantissa: 23 bits 4233 * +0.0 : 0 0x00 0x000000 => 0x00000000 4234 * -0.0 : 1 0x00 0x000000 => 0x80000000 4235 * +infinity : 0 0xFF 0x000000 => 0x7F800000 4236 * -infinity : 1 0xFF 0x000000 => 0xFF800000 4237 * +QNaN : 0 0xFF 0x3FFFFF => 0x7FBFFFFF 4238 * -QNaN : 1 0xFF 0x3FFFFF => 0xFFBFFFFF 4239 * +SNaN : 0 0xFF 0x400000 => 0x7FC00000 4240 * -SNaN : 1 0xFF 0x400000 => 0xFFC00000 4241 */ 4242 uint64_t mant; 4243 uint16_t _exp, e0, e1; 4244 int s; 4245 int i=0; 4246 4247 /* Note: VEX isn't so hot with denormals, so don't bother 4248 testing them: set _exp > 0 4249 */ 4250 4251 if ( arg_list_size == 1 ) { // Large 4252 fargs = malloc(200 * sizeof(double)); 4253 for (s=0; s<2; s++) { 4254 for (e0=0; e0<2; e0++) { 4255 for (e1=0x001; ; e1 = ((e1 + 1) << 2) + 6) { 4256 if (e1 >= 0x400) 4257 e1 = 0x3fe; 4258 _exp = (e0 << 10) | e1; 4259 for (mant = 0x0000000000001ULL; mant < (1ULL << 52); 4260 /* Add 'random' bits */ 4261 mant = ((mant + 0x4A6) << 13) + 0x359) { 4262 register_farg(&fargs[i++], s, _exp, mant); 4263 } 4264 if (e1 == 0x3fe) 4265 break; 4266 } 4267 } 4268 } 4269 } else { // Default 4270 fargs = malloc(16 * sizeof(double)); 4271 for (s=0; s<2; s++) { // x2 4272 // for (e0=0; e0<2; e0++) { 4273 for (e1=0x001; ; e1 = ((e1 + 1) << 13) + 7) { // x2 4274 // for (e1=0x001; ; e1 = ((e1 + 1) << 5) + 7) { // x3 4275 if (e1 >= 0x400) 4276 e1 = 0x3fe; 4277 // _exp = (e0 << 10) | e1; 4278 _exp = e1; 4279 for (mant = 0x0000000000001ULL; mant < (1ULL << 52); 4280 /* Add 'random' bits */ 4281 mant = ((mant + 0x4A6) << 29) + 0x359) { // x2 4282 register_farg(&fargs[i++], s, _exp, mant); 4283 } 4284 if (e1 == 0x3fe) 4285 break; 4286 } 4287 // } 4288 } 4289 } 4290 4291 /* To iterate over non-special values only */ 4292 nb_normal_fargs = i; 4293 4294 4295 /* Special values */ 4296 /* +0.0 : 0 0x000 0x0000000000000 */ 4297 s = 0; 4298 _exp = 0x000; 4299 mant = 0x0000000000000ULL; 4300 register_farg(&fargs[i++], s, _exp, mant); 4301 /* -0.0 : 1 0x000 0x0000000000000 */ 4302 s = 1; 4303 _exp = 0x000; 4304 mant = 0x0000000000000ULL; 4305 register_farg(&fargs[i++], s, _exp, mant); 4306 /* +infinity : 0 0x7FF 0x0000000000000 */ 4307 s = 0; 4308 _exp = 0x7FF; 4309 mant = 0x0000000000000ULL; 4310 register_farg(&fargs[i++], s, _exp, mant); 4311 /* -infinity : 1 0x7FF 0x0000000000000 */ 4312 s = 1; 4313 _exp = 0x7FF; 4314 mant = 0x0000000000000ULL; 4315 register_farg(&fargs[i++], s, _exp, mant); 4316 /* +QNaN : 0 0x7FF 0x7FFFFFFFFFFFF */ 4317 s = 0; 4318 _exp = 0x7FF; 4319 mant = 0x7FFFFFFFFFFFFULL; 4320 register_farg(&fargs[i++], s, _exp, mant); 4321 /* -QNaN : 1 0x7FF 0x7FFFFFFFFFFFF */ 4322 s = 1; 4323 _exp = 0x7FF; 4324 mant = 0x7FFFFFFFFFFFFULL; 4325 register_farg(&fargs[i++], s, _exp, mant); 4326 /* +SNaN : 0 0x7FF 0x8000000000000 */ 4327 s = 0; 4328 _exp = 0x7FF; 4329 mant = 0x8000000000000ULL; 4330 register_farg(&fargs[i++], s, _exp, mant); 4331 /* -SNaN : 1 0x7FF 0x8000000000000 */ 4332 s = 1; 4333 _exp = 0x7FF; 4334 mant = 0x8000000000000ULL; 4335 register_farg(&fargs[i++], s, _exp, mant); 4336 AB_DPRINTF("Registered %d fargs values\n", i); 4337 4338 nb_fargs = i; 4339 } 4340 4341 static void build_iargs_table (void) 4342 { 4343 uint64_t tmp; 4344 int i=0; 4345 4346 #ifndef __powerpc64__ 4347 if (arg_list_size == 1) { // Large 4348 iargs = malloc(400 * sizeof(HWord_t)); 4349 for (tmp=0; ; tmp = tmp + 1 + (tmp >> 1)) { 4350 if (tmp >= 0x100000000ULL) 4351 tmp = 0xFFFFFFFF; 4352 iargs[i++] = (HWord_t)tmp; 4353 AB_DPRINTF("val %08x\n", (HWord_t)tmp); 4354 if (tmp == 0xFFFFFFFF) 4355 break; 4356 } 4357 } else { // Default 4358 iargs = malloc(10 * sizeof(HWord_t)); 4359 // for (tmp = 0; ; tmp = 71*tmp + 1 + (tmp>>1)) { // gives 8 4360 // for (tmp = 0; ; tmp = 100000*tmp + 1 + (tmp>>1)) { // gives 4 4361 for (tmp=0; ; tmp = 999999*tmp + 999999) { // gives 3 4362 if (tmp >= 0x100000000ULL) 4363 tmp = 0xFFFFFFFF; 4364 iargs[i++] = (HWord_t)tmp; 4365 AB_DPRINTF("val %08x\n", (HWord_t)tmp); 4366 if (tmp == 0xFFFFFFFF) 4367 break; 4368 } 4369 } 4370 #else 4371 if (arg_list_size == 1) { // Large 4372 iargs = malloc(800 * sizeof(HWord_t)); 4373 for (tmp=0; ; tmp = 2*tmp + 1 + (tmp >> 2)) { 4374 if ((long)tmp < 0 ) 4375 tmp = 0xFFFFFFFFFFFFFFFFULL; 4376 iargs[i++] = tmp; 4377 AB_DPRINTF("val %016lx\n", tmp); 4378 if (tmp == 0xFFFFFFFFFFFFFFFFULL) 4379 break; 4380 } 4381 } else { // Default 4382 iargs = malloc(20 * sizeof(HWord_t)); 4383 // for (tmp=0; ; tmp = 9999*tmp + 999999) { // gives 6 4384 for (tmp = 0; ; tmp = 123456789*tmp + 123456789999) { // gives 3 4385 if ((long)tmp < 0 ) 4386 tmp = 0xFFFFFFFFFFFFFFFFULL; 4387 iargs[i++] = tmp; 4388 AB_DPRINTF("val %016lx\n", tmp); 4389 if (tmp == 0xFFFFFFFFFFFFFFFFULL) 4390 break; 4391 } 4392 } 4393 #endif // #ifndef __powerpc64__ 4394 4395 AB_DPRINTF("Registered %d iargs values\n", i); 4396 nb_iargs = i; 4397 } 4398 4399 static void build_ii16_table (void) 4400 { 4401 uint32_t tmp; 4402 int i=0; 4403 4404 if (arg_list_size == 1) { // Large 4405 ii16 = malloc(200 * sizeof(uint32_t)); 4406 for (tmp=0; ; tmp = tmp + 1 + (tmp >> 2)) { 4407 if (tmp >= 0x10000) 4408 tmp = 0xFFFF; 4409 ii16[i++] = tmp; 4410 AB_DPRINTF("val %04x\n", tmp); 4411 if (tmp == 0xFFFF) 4412 break; 4413 } 4414 } else { // Default 4415 ii16 = malloc(10 * sizeof(uint32_t)); 4416 for (tmp=0; ; tmp = 999*tmp + 999) { // gives 3 4417 if (tmp >= 0x10000) 4418 tmp = 0xFFFF; 4419 ii16[i++] = tmp; 4420 AB_DPRINTF("val %04x\n", tmp); 4421 if (tmp == 0xFFFF) 4422 break; 4423 } 4424 } 4425 AB_DPRINTF("Registered %d ii16 values\n", i); 4426 nb_ii16 = i; 4427 } 4428 4429 #if defined (HAS_ALTIVEC) 4430 static void build_viargs_table (void) 4431 { 4432 #if !defined (ALTIVEC_ARGS_LARGE) 4433 unsigned int i=2; 4434 viargs = memalign16(i * sizeof(vector unsigned int)); 4435 viargs[0] = (vector unsigned int) { 0x01020304,0x05060708,0x090A0B0C,0x0E0D0E0F }; 4436 AB_DPRINTF_VEC32x4( viargs[0] ); 4437 viargs[1] = (vector unsigned int) { 0xF1F2F3F4,0xF5F6F7F8,0xF9FAFBFC,0xFEFDFEFF }; 4438 AB_DPRINTF_VEC32x4( viargs[1] ); 4439 #else 4440 unsigned int i,j; 4441 // build from iargs table (large/default already set) 4442 viargs = malloc(nb_iargs * sizeof(vector unsigned int)); 4443 for (i=0; i<nb_iargs; i++) { 4444 j = iargs[i]; 4445 viargs[i] = (vector unsigned int){ j, j*2, j*3, j*4 }; 4446 AB_DPRINTF_VEC32x4( viargs[i] ); 4447 } 4448 #endif 4449 4450 AB_DPRINTF("Registered %d viargs values\n", i); 4451 nb_viargs = i; 4452 } 4453 4454 static inline void register_vfarg (vector float* vfarg, 4455 int s, uint8_t _exp, uint32_t mant) 4456 { 4457 uint32_t tmp; 4458 vector uint32_t* vfargI = (vector uint32_t*)vfarg; 4459 4460 tmp = ((uint64_t)s << 31) | ((uint64_t)_exp << 23) | mant; 4461 *vfargI = (vector uint32_t){ tmp,tmp,tmp,tmp }; 4462 AB_DPRINTF("%d %02x %06x => %08x %0e\n", 4463 s, _exp, mant, *((uint32_t*)&tmp), *(float*)&tmp); 4464 } 4465 4466 static void build_vfargs_table (void) 4467 { 4468 /* Sign goes from zero to one 4469 * Exponent goes from 0 to ((1 << 9) - 1) 4470 * Mantissa goes from 1 to ((1 << 24) - 1) 4471 * + special values: 4472 * +0.0 : 0 0x00 0x000000 => 0x00000000 4473 * -0.0 : 1 0x00 0x000000 => 0x80000000 4474 * +infinity : 0 0xFF 0x000000 => 0x7F800000 4475 * -infinity : 1 0xFF 0x000000 => 0xFF800000 4476 * +SNaN : 0 0xFF 0x7FFFFF (non-zero) => 0x7FFFFFFF 4477 * -SNaN : 1 0xFF 0x7FFFFF (non-zero) => 0xFFFFFFFF 4478 * +QNaN : 0 0xFF 0x3FFFFF (non-zero) => 0x7FBFFFFF 4479 * -QNaN : 1 0xFF 0x3FFFFF (non-zero) => 0xFFBFFFFF 4480 * (8 values) 4481 */ 4482 uint32_t mant; 4483 uint16_t _exp; 4484 int s; 4485 int i=0; 4486 4487 4488 #if !defined (ALTIVEC_ARGS_LARGE) 4489 nb_vfargs = 12; 4490 vfargs = memalign16(nb_vfargs * sizeof(vector float)); 4491 4492 // 4 values: 4493 for (s=0; s<2; s++) { 4494 for (_exp=0x5; ; _exp += 0x9D ) { 4495 if (_exp > 0xDF) 4496 break; 4497 for (mant = 0x3FFFFF; mant < 0x7FFFFF; 4498 mant = /* random */ ((mant + 0x1A6) << 31) + 0x159) { 4499 register_vfarg(&vfargs[i++], s, (uint8_t)_exp, mant); 4500 } 4501 } 4502 } 4503 #else 4504 nb_vfargs = 50; 4505 vfargs = memalign16(nb_vfargs * sizeof(vector float)); 4506 4507 for (s=0; s<2; s++) { 4508 for (_exp=0x0; ; _exp += 0x3F ) { 4509 // for (_exp=0; ; _exp = ((_exp + 1) << 1) + 3) { 4510 if (_exp >= 0xFE) 4511 _exp = 0xFE; 4512 for (mant = 0x0; mant < 0x7FFFFF; 4513 mant = /* random */ ((mant + 0x4A6) << 5) + 0x359) { 4514 register_vfarg(&vfargs[i++], s, (uint8_t)_exp, mant); 4515 } 4516 if (_exp >= 0xFE) 4517 break; 4518 } 4519 } 4520 #endif 4521 4522 /* Special values */ 4523 /* +0.0 : 0 0x00 0x000000 */ 4524 s = 0; 4525 _exp = 0x00; 4526 mant = 0x000000; 4527 register_vfarg(&vfargs[i++], s, _exp, mant); 4528 /* -0.0 : 1 0x00 0x000000 */ 4529 s = 1; 4530 _exp = 0x00; 4531 mant = 0x000000; 4532 register_vfarg(&vfargs[i++], s, _exp, mant); 4533 4534 /* +infinity : 0 0xFF 0x000000 */ 4535 s = 0; 4536 _exp = 0xFF; 4537 mant = 0x000000; 4538 register_vfarg(&vfargs[i++], s, _exp, mant); 4539 /* -infinity : 1 0xFF 0x000000 */ 4540 s = 1; 4541 _exp = 0xFF; 4542 mant = 0x000000; 4543 register_vfarg(&vfargs[i++], s, _exp, mant); 4544 4545 /* NaN: _exponent all 1s, non-zero fraction */ 4546 /* SNaN is a NaN with the most significant fraction bit clear.*/ 4547 /* +SNaN : 0 0xFF 0x7FFFFF */ 4548 s = 0; 4549 _exp = 0xFF; 4550 mant = 0x7FFFFF; 4551 register_vfarg(&vfargs[i++], s, _exp, mant); 4552 /* -SNaN : 1 0xFF 0x7FFFFF */ 4553 s = 1; 4554 _exp = 0xFF; 4555 mant = 0x7FFFFF; 4556 register_vfarg(&vfargs[i++], s, _exp, mant); 4557 4558 /* QNaN is a NaN with the most significant fraction bit set */ 4559 /* +QNaN : 0 0xFF 0x3F0000 */ 4560 s = 0; 4561 _exp = 0xFF; 4562 mant = 0x3FFFFF; 4563 register_vfarg(&vfargs[i++], s, _exp, mant); 4564 /* -QNaN : 1 0xFF 0x3F0000 */ 4565 s = 1; 4566 _exp = 0xFF; 4567 mant = 0x3FFFFF; 4568 register_vfarg(&vfargs[i++], s, _exp, mant); 4569 AB_DPRINTF("Registered %d vfargs values\n", i); 4570 4571 assert(i <= nb_vfargs); 4572 nb_vfargs = i; 4573 } 4574 #endif 4575 4576 #if 0 4577 static void dump_iargs (void) 4578 { 4579 int i; 4580 for (i = 0; i < nb_iargs; i++) { 4581 printf("iarg %d: %08x %08x %08x\n", i, iargs[i], 4582 (unsigned int)&iargs[i], (unsigned int)iargs); 4583 } 4584 } 4585 4586 static void dump_iargs16 (void) 4587 { 4588 int i; 4589 for (i = 0; i < nb_ii16; i++) { 4590 printf("iarg16 %d: %08x %08x %08x\n", i, ii16[i], 4591 (unsigned int)&ii16[i], (unsigned int)ii16); 4592 } 4593 } 4594 4595 static void dump_vfargs (void) 4596 { 4597 vector float vf; 4598 float f; 4599 int i=0; 4600 for (i=0; i<nb_vfargs; i++) { 4601 vf = (vector float)vfargs[i]; 4602 f = ((float*)&vf)[0]; 4603 printf("vfarg %3d: %24f : %08x\n", i, f, ((unsigned int*)&f)[0]); 4604 } 4605 } 4606 #endif 4607 4608 static void test_int_three_args (const char* name, test_func_t func, 4609 unused uint32_t test_flags) 4610 { 4611 volatile HWord_t res; 4612 volatile uint32_t flags, xer; 4613 int i, j, k; 4614 4615 for (i=0; i<nb_iargs; i++) { 4616 for (j=0; j<nb_iargs; j++) { 4617 for (k=0; k<nb_iargs; k++) { 4618 r14 = iargs[i]; 4619 r15 = iargs[j]; 4620 r16 = iargs[k]; 4621 4622 SET_CR_XER_ZERO; 4623 (*func)(); 4624 GET_CR_XER(flags,xer); 4625 res = r17; 4626 4627 #ifndef __powerpc64__ 4628 printf("%s %08x, %08x, %08x => %08x (%08x %08x)\n", 4629 #else 4630 printf("%s %016llx, %016llx, %016llx => %016llx (%08x %08x)\n", 4631 #endif 4632 name, iargs[i], iargs[j], iargs[k], res, flags, xer); 4633 } 4634 if (verbose) printf("\n"); 4635 } 4636 } 4637 } 4638 4639 static void test_int_two_args (const char* name, test_func_t func, 4640 uint32_t test_flags) 4641 { 4642 volatile HWord_t res; 4643 volatile uint32_t flags, xer, xer_orig; 4644 int i, j, is_div; 4645 #ifdef __powerpc64__ 4646 int zap_hi32; 4647 #endif 4648 4649 // catches div, divwu, divo, divwu, divwuo, and . variants 4650 is_div = strstr(name, "divw") != NULL; 4651 4652 #ifdef __powerpc64__ 4653 zap_hi32 = strstr(name, "mulhw") != NULL; 4654 #endif 4655 4656 xer_orig = 0x00000000; 4657 redo: 4658 for (i=0; i<nb_iargs; i++) { 4659 for (j=0; j<nb_iargs; j++) { 4660 4661 /* result of division by zero is implementation dependent. 4662 don't test it. */ 4663 if (is_div && iargs[j] == 0) 4664 continue; 4665 4666 r14 = iargs[i]; 4667 r15 = iargs[j]; 4668 4669 SET_XER(xer_orig); 4670 SET_CR_ZERO; 4671 (*func)(); 4672 GET_CR_XER(flags,xer); 4673 res = r17; 4674 4675 #ifndef __powerpc64__ 4676 printf("%s %08x, %08x => %08x (%08x %08x)\n", 4677 #else 4678 if (zap_hi32) res &= 0xFFFFFFFFULL; 4679 printf("%s %016llx, %016llx => %016llx (%08x %08x)\n", 4680 #endif 4681 name, iargs[i], iargs[j], res, flags, xer); 4682 } 4683 if (verbose) printf("\n"); 4684 } 4685 if ((test_flags & PPC_XER_CA) && xer_orig == 0x00000000) { 4686 xer_orig = 0x20000000; 4687 goto redo; 4688 } 4689 } 4690 4691 static void test_int_one_arg (const char* name, test_func_t func, 4692 uint32_t test_flags) 4693 { 4694 volatile HWord_t res; 4695 volatile uint32_t flags, xer, xer_orig; 4696 int i; 4697 4698 xer_orig = 0x00000000; 4699 redo: 4700 for (i=0; i<nb_iargs; i++) { 4701 r14 = iargs[i]; 4702 SET_XER(xer_orig); 4703 SET_CR_ZERO; 4704 (*func)(); 4705 res = r17; 4706 GET_CR_XER(flags,xer); 4707 4708 #ifndef __powerpc64__ 4709 printf("%s %08x => %08x (%08x %08x)\n", 4710 #else 4711 printf("%s %016llx => %016llx (%08x %08x)\n", 4712 #endif 4713 name, iargs[i], res, flags, xer); 4714 } 4715 if ((test_flags & PPC_XER_CA) && xer_orig == 0x00000000) { 4716 xer_orig = 0x20000000; 4717 goto redo; 4718 } 4719 } 4720 4721 static inline void invalidate_icache ( void *ptr, int nbytes ) 4722 { 4723 HWord_t startaddr = (HWord_t) ptr; 4724 HWord_t endaddr = startaddr + nbytes; 4725 HWord_t cls = 32; /*VG_(cache_line_size_ppc32);*/ 4726 HWord_t addr; 4727 4728 startaddr &= ~(cls - 1); 4729 for (addr = startaddr; addr < endaddr; addr += cls) 4730 asm volatile("dcbst 0,%0" : : "r" (addr)); 4731 asm volatile("sync"); 4732 for (addr = startaddr; addr < endaddr; addr += cls) 4733 asm volatile("icbi 0,%0" : : "r" (addr)); 4734 asm volatile("sync; isync"); 4735 } 4736 4737 /* for god knows what reason, if this isn't inlined, the 4738 program segfaults. */ 4739 static inline 4740 void _patch_op_imm (uint32_t *p_insn, uint16_t imm, int sh, int len) 4741 { 4742 uint32_t mask = ((1 << len) - 1) << sh; 4743 *p_insn = (*p_insn & ~mask) | ((imm<<sh) & mask); 4744 } 4745 4746 static inline 4747 void patch_op_imm (uint32_t* p_insn, uint16_t imm, int sh, int len) 4748 { 4749 _patch_op_imm(p_insn, imm, sh, len); 4750 invalidate_icache(p_insn, 4); 4751 } 4752 4753 static inline 4754 void patch_op_imm16 (uint32_t *p_insn, uint16_t imm) 4755 { 4756 patch_op_imm(p_insn, imm, 0, 16); 4757 } 4758 4759 4760 /* Copy the 2 insn function starting at p_func_F to func_buf[], and 4761 return a possibly different pointer, which, when called, runs the 4762 copy in func_buf[]. */ 4763 static inline 4764 test_func_t init_function( test_func_t p_func_F, uint32_t func_buf[] ) 4765 { 4766 uint32_t* p_func = (uint32_t*)p_func_F; 4767 #ifndef __powerpc64__ 4768 func_buf[0] = p_func[0]; 4769 func_buf[1] = p_func[1]; 4770 return (test_func_t)&func_buf[0]; 4771 #else 4772 /* p_func points to a function descriptor, the first word of which 4773 points to the real code. Copy the code itself but not the 4774 descriptor, and just swizzle the descriptor's entry pointer. */ 4775 uint64_t* descr = (uint64_t*)p_func; 4776 uint32_t* entry = (uint32_t*)(descr[0]); 4777 func_buf[0] = entry[0]; 4778 func_buf[1] = entry[1]; 4779 descr[0] = (uint64_t)&func_buf[0]; 4780 return (test_func_t)descr; 4781 #endif // #ifndef __powerpc64__ 4782 } 4783 4784 4785 static void test_int_one_reg_imm16 (const char* name, 4786 test_func_t func_IN, 4787 unused uint32_t test_flags) 4788 { 4789 volatile test_func_t func; 4790 uint32_t* func_buf = get_rwx_area(); 4791 volatile HWord_t res; 4792 volatile uint32_t flags, xer; 4793 int i, j; 4794 4795 for (i=0; i<nb_iargs; i++) { 4796 for (j=0; j<nb_ii16; j++) { 4797 /* Patch up the instruction */ 4798 func = init_function( func_IN, func_buf ); 4799 patch_op_imm16(&func_buf[0], ii16[j]); 4800 4801 r14 = iargs[i]; 4802 4803 SET_CR_XER_ZERO; 4804 (*func)(); 4805 GET_CR_XER(flags,xer); 4806 res = r17; 4807 4808 #ifndef __powerpc64__ 4809 printf("%s %08x, %08x => %08x (%08x %08x)\n", 4810 #else 4811 printf("%s %016llx, %08x => %016llx (%08x %08x)\n", 4812 #endif 4813 name, iargs[i], ii16[j], res, flags, xer); 4814 } 4815 if (verbose) printf("\n"); 4816 } 4817 } 4818 4819 /* Special test cases for: 4820 * rlwimi 4821 * rlwinm 4822 * rlwnm 4823 * srawi 4824 * mcrf 4825 * mcrfs 4826 * mcrxr_cb 4827 * mfcr_cb 4828 * mfspr_cb 4829 * mftb_cb 4830 * mtcrf_cb 4831 * mtspr_cb 4832 4833 __powerpc64__ only: 4834 * rldcl rA,rS,SH,MB 4835 * rldcr rA,rS,SH,ME 4836 * rldic rA,rS,SH,MB 4837 * rldicl rA,rS,SH,MB 4838 * rldicr rA,rS,SH,ME 4839 * rldimi rA,rS,SH,MB 4840 * sradi rA,rS,SH 4841 */ 4842 4843 static void rlwi_cb (const char* name, test_func_t func_IN, 4844 unused uint32_t test_flags) 4845 { 4846 volatile test_func_t func; 4847 uint32_t* func_buf = get_rwx_area(); 4848 volatile HWord_t res; 4849 volatile uint32_t flags, xer; 4850 int i, j, k, l, arg_step; 4851 4852 arg_step = (arg_list_size == 0) ? 31 : 3; 4853 4854 r17 = 0; // rlwimi takes r17 as input: start with a clean slate. 4855 4856 for (i=0; i<nb_iargs; i++) { 4857 for (j=0; j<32; j+=arg_step) { 4858 for (k=0; k<32; k+=arg_step) { 4859 for (l=0; l<32; l+=arg_step) { 4860 /* Patch up the instruction */ 4861 func = init_function( func_IN, func_buf ); 4862 _patch_op_imm(&func_buf[0], j, 11, 5); 4863 _patch_op_imm(&func_buf[0], k, 6, 5); 4864 patch_op_imm(&func_buf[0], l, 1, 5); 4865 4866 r14 = iargs[i]; 4867 4868 SET_CR_XER_ZERO; 4869 (*func)(); 4870 GET_CR_XER(flags,xer); 4871 res = r17; 4872 4873 #ifndef __powerpc64__ 4874 printf("%s %08x, %2d, %2d, %2d => %08x (%08x %08x)\n", 4875 #else 4876 printf("%s %016llx, %2d, %2d, %2d => %016llx (%08x %08x)\n", 4877 #endif 4878 name, iargs[i], j, k, l, res, flags, xer); 4879 } 4880 if (verbose) printf("\n"); 4881 } 4882 } 4883 } 4884 } 4885 4886 static void rlwnm_cb (const char* name, test_func_t func_IN, 4887 unused uint32_t test_flags) 4888 { 4889 volatile test_func_t func; 4890 uint32_t* func_buf = get_rwx_area(); 4891 volatile HWord_t res; 4892 volatile uint32_t flags, xer; 4893 int i, j, k, l, arg_step; 4894 4895 arg_step = (arg_list_size == 0) ? 31 : 3; 4896 4897 for (i=0; i<nb_iargs; i++) { 4898 for (j=0; j<nb_iargs; j++) { 4899 for (k=0; k<32; k+=arg_step) { 4900 for (l=0; l<32; l+=arg_step) { 4901 /* Patch up the instruction */ 4902 func = init_function( func_IN, func_buf ); 4903 _patch_op_imm(&func_buf[0], k, 6, 5); 4904 patch_op_imm(&func_buf[0], l, 1, 5); 4905 4906 r14 = iargs[i]; 4907 r15 = iargs[j]; 4908 4909 SET_CR_XER_ZERO; 4910 (*func)(); 4911 GET_CR_XER(flags,xer); 4912 res = r17; 4913 4914 #ifndef __powerpc64__ 4915 printf("%s %08x, %08x, %2d, %2d => %08x (%08x %08x)\n", 4916 #else 4917 printf("%s %016llx, %016llx, %2d, %2d => %016llx (%08x %08x)\n", 4918 #endif 4919 name, iargs[i], iargs[j], k, l, res, flags, xer); 4920 } 4921 if (verbose) printf("\n"); 4922 } 4923 } 4924 } 4925 } 4926 4927 static void srawi_cb (const char* name, test_func_t func_IN, 4928 unused uint32_t test_flags) 4929 { 4930 volatile test_func_t func; 4931 uint32_t* func_buf = get_rwx_area(); 4932 volatile HWord_t res; 4933 volatile uint32_t flags, xer; 4934 int i, j, arg_step; 4935 4936 arg_step = (arg_list_size == 0) ? 31 : 1; 4937 4938 for (i=0; i<nb_iargs; i++) { 4939 for (j=0; j<32; j+=arg_step) { 4940 /* Patch up the instruction */ 4941 func = init_function( func_IN, func_buf ); 4942 patch_op_imm(&func_buf[0], j, 11, 5); 4943 4944 r14 = iargs[i]; 4945 4946 SET_CR_XER_ZERO; 4947 (*func)(); 4948 GET_CR_XER(flags,xer); 4949 res = r17; 4950 4951 #ifndef __powerpc64__ 4952 printf("%s %08x, %2d => %08x (%08x %08x)\n", 4953 #else 4954 printf("%s %016llx, %2d => %016llx (%08x %08x)\n", 4955 #endif 4956 name, iargs[i], j, res, flags, xer); 4957 } 4958 if (verbose) printf("\n"); 4959 } 4960 } 4961 4962 static void mcrf_cb (const char* name, test_func_t func_IN, 4963 unused uint32_t test_flags) 4964 { 4965 volatile test_func_t func; 4966 uint32_t* func_buf = get_rwx_area(); 4967 volatile uint32_t flags, xer; 4968 int i, j, k, arg_step; 4969 4970 arg_step = (arg_list_size == 0) ? 7 : 1; 4971 4972 for (i=0; i<nb_iargs; i++) { 4973 for (j=0; j<8; j+=arg_step) { 4974 for (k=0; k<8; k+=arg_step) { 4975 /* Patch up the instruction */ 4976 func = init_function( func_IN, func_buf ); 4977 _patch_op_imm(&func_buf[0], j, 23, 3); 4978 patch_op_imm(&func_buf[0], k, 18, 3); 4979 4980 r14 = iargs[i]; 4981 4982 SET_CR(r14); 4983 SET_XER_ZERO; 4984 (*func)(); 4985 GET_CR_XER(flags,xer); 4986 4987 #ifndef __powerpc64__ 4988 printf("%s %d, %d (%08x) => (%08x %08x)\n", 4989 #else 4990 printf("%s %d, %d (%016llx) => (%08x %08x)\n", 4991 #endif 4992 name, j, k, iargs[i], flags, xer); 4993 } 4994 if (verbose) printf("\n"); 4995 } 4996 } 4997 } 4998 4999 static void mcrxr_cb (const char* name, test_func_t func_IN, 5000 unused uint32_t test_flags) 5001 { 5002 volatile test_func_t func; 5003 uint32_t* func_buf = get_rwx_area(); 5004 volatile uint32_t flags, xer; 5005 int i, j, k, arg_step; 5006 5007 arg_step = 1; //(arg_list_size == 0) ? 7 : 1; 5008 5009 for (i=0; i<16; i+=arg_step) { 5010 j = i << 28; 5011 for (k=0; k<8; k+=arg_step) { 5012 /* Patch up the instruction */ 5013 func = init_function( func_IN, func_buf ); 5014 patch_op_imm(&func_buf[0], k, 23, 3); 5015 5016 r14 = j; 5017 5018 SET_CR_ZERO; 5019 SET_XER(r14); 5020 (*func)(); 5021 GET_CR_XER(flags,xer); 5022 5023 printf("%s %d (%08x) => (%08x %08x)\n", 5024 name, k, j, flags, xer); 5025 } 5026 if (verbose) printf("\n"); 5027 } 5028 } 5029 5030 static void mfcr_cb (const char* name, test_func_t func, 5031 unused uint32_t test_flags) 5032 { 5033 volatile HWord_t res; 5034 volatile uint32_t flags, xer; 5035 int i; 5036 5037 for (i=0; i<nb_iargs; i++) { 5038 r14 = iargs[i]; 5039 5040 /* Set up flags for test */ 5041 SET_CR(r14); 5042 SET_XER_ZERO; 5043 (*func)(); 5044 GET_CR_XER(flags,xer); 5045 res = r17; 5046 5047 #ifndef __powerpc64__ 5048 printf("%s (%08x) => %08x (%08x %08x)\n", 5049 #else 5050 printf("%s (%016llx) => %016llx (%08x %08x)\n", 5051 #endif 5052 name, iargs[i], res, flags, xer); 5053 } 5054 } 5055 5056 // NOTE: Not using func: calling function kills lr 5057 static void mfspr_cb (const char* name, test_func_t func, 5058 unused uint32_t test_flags) 5059 { 5060 //volatile uint32_t res, flags, xer, ctr, lr, tmpcr, tmpxer; 5061 volatile HWord_t res; 5062 int j, k; 5063 func = func; // just to stop compiler complaining 5064 5065 // mtxer followed by mfxer 5066 for (k=0; k<nb_iargs; k++) { 5067 j = iargs[k]; 5068 __asm__ __volatile__( 5069 "mtxer %1\n" 5070 "\tmfxer %0" 5071 : /*out*/"=b"(res) : /*in*/"b"(j) : /*trashed*/"xer" 5072 ); 5073 res &= 0xE000007F; /* rest of the bits are undefined */ 5074 5075 #ifndef __powerpc64__ 5076 printf("%s 1 (%08x) -> mtxer -> mfxer => %08x\n", 5077 #else 5078 printf("%s 1 (%08x) -> mtxer -> mfxer => %016llx\n", 5079 #endif 5080 name, j, res); 5081 } 5082 5083 // mtlr followed by mflr 5084 for (k=0; k<nb_iargs; k++) { 5085 j = iargs[k]; 5086 __asm__ __volatile__( 5087 "mtlr %1\n" 5088 "\tmflr %0" 5089 : /*out*/"=b"(res) : /*in*/"b"(j) : /*trashed*/"lr" 5090 ); 5091 5092 #ifndef __powerpc64__ 5093 printf("%s 8 (%08x) -> mtlr -> mflr => %08x\n", 5094 #else 5095 printf("%s 8 (%08x) -> mtlr -> mflr => %016llx\n", 5096 #endif 5097 name, j, res); 5098 } 5099 5100 // mtctr followed by mfctr 5101 for (k=0; k<nb_iargs; k++) { 5102 j = iargs[k]; 5103 __asm__ __volatile__( 5104 "mtctr %1\n" 5105 "\tmfctr %0" 5106 : /*out*/"=b"(res) : /*in*/"b"(j) : /*trashed*/"ctr" 5107 ); 5108 5109 #ifndef __powerpc64__ 5110 printf("%s 9 (%08x) -> mtctr -> mfctr => %08x\n", 5111 #else 5112 printf("%s 9 (%08x) -> mtctr -> mfctr => %016llx\n", 5113 #endif 5114 name, j, res); 5115 } 5116 } 5117 5118 static void mtcrf_cb (const char* name, test_func_t func_IN, 5119 unused uint32_t test_flags) 5120 { 5121 volatile test_func_t func; 5122 uint32_t* func_buf = get_rwx_area(); 5123 volatile uint32_t flags, xer; 5124 int i, j, arg_step; 5125 5126 arg_step = (arg_list_size == 0) ? 99 : 1; 5127 5128 for (i=0; i<nb_iargs; i++) { 5129 for (j=0; j<256; j+=arg_step) { 5130 /* Patch up the instruction */ 5131 func = init_function( func_IN, func_buf ); 5132 patch_op_imm(&func_buf[0], j, 12, 8); 5133 5134 r14 = iargs[i]; 5135 5136 SET_CR_XER_ZERO; 5137 (*func)(); 5138 GET_CR_XER(flags,xer); 5139 5140 #ifndef __powerpc64__ 5141 printf("%s %3d, %08x => (%08x %08x)\n", 5142 #else 5143 printf("%s %3d, %016llx => (%08x %08x)\n", 5144 #endif 5145 name, j, iargs[i], flags, xer); 5146 } 5147 if (verbose) printf("\n"); 5148 } 5149 } 5150 5151 // NOTE: Not using func: calling function kills lr 5152 static void mtspr_cb (const char* name, test_func_t func, 5153 unused uint32_t test_flags) 5154 { 5155 } 5156 5157 #ifdef __powerpc64__ 5158 static void rldc_cb (const char* name, test_func_t func_IN, 5159 unused uint32_t test_flags) 5160 { 5161 volatile test_func_t func; 5162 uint32_t* func_buf = get_rwx_area(); 5163 volatile HWord_t res; 5164 volatile uint32_t flags, xer; 5165 int i, j, k, arg_step; 5166 5167 arg_step = (arg_list_size == 0) ? 7 : 3; 5168 5169 for (i=0; i<nb_iargs; i++) { 5170 for (j=0; j<nb_iargs; j++) { 5171 for (k=0; k<64; k+=arg_step) { 5172 /* Patch up the instruction */ 5173 func = init_function( func_IN, func_buf ); 5174 patch_op_imm(&func_buf[0], (((k & 0x1F)<<1) | ((k>>5)&1)), 5, 6); 5175 5176 r14 = iargs[i]; 5177 r15 = iargs[j]; 5178 5179 SET_CR_XER_ZERO; 5180 (*func)(); 5181 GET_CR_XER(flags,xer); 5182 res = r17; 5183 5184 printf("%s %016llx, %016llx, %2d => %016llx (%08x %08x)\n", 5185 name, iargs[i], iargs[j], k, res, flags, xer); 5186 } 5187 if (verbose) printf("\n"); 5188 } 5189 } 5190 } 5191 5192 static void rldi_cb (const char* name, test_func_t func_IN, 5193 unused uint32_t test_flags) 5194 { 5195 volatile test_func_t func; 5196 uint32_t* func_buf = get_rwx_area(); 5197 volatile HWord_t res; 5198 volatile uint32_t flags, xer; 5199 int i, j, k, arg_step; 5200 5201 arg_step = (arg_list_size == 0) ? 7 : 3; 5202 5203 for (i=0; i<nb_iargs; i++) { 5204 for (j=0; j<64; j+=arg_step) { // SH 5205 for (k=0; k<64; k+=arg_step) { // MB|ME 5206 /* Patch up the instruction */ 5207 func = init_function( func_IN, func_buf ); 5208 _patch_op_imm(&func_buf[0], (j & 0x1F), 11, 5); 5209 _patch_op_imm(&func_buf[0], ((j>>5)&1), 1, 1); 5210 patch_op_imm(&func_buf[0], (((k & 0x1F)<<1) | ((k>>5)&1)), 5, 6); 5211 5212 r14 = iargs[i]; 5213 5214 SET_CR_XER_ZERO; 5215 (*func)(); 5216 GET_CR_XER(flags,xer); 5217 res = r17; 5218 5219 printf("%s %016llx, %2d, %2d => %016llx (%08x %08x)\n", 5220 name, iargs[i], j, k, res, flags, xer); 5221 } 5222 if (verbose) printf("\n"); 5223 } 5224 } 5225 } 5226 5227 static void sradi_cb (const char* name, test_func_t func_IN, 5228 unused uint32_t test_flags) 5229 { 5230 volatile test_func_t func; 5231 uint32_t* func_buf = get_rwx_area(); 5232 volatile HWord_t res; 5233 volatile uint32_t flags, xer; 5234 int i, j, arg_step; 5235 5236 arg_step = (arg_list_size == 0) ? 7 : 3; 5237 5238 for (i=0; i<nb_iargs; i++) { 5239 for (j=0; j<64; j+=arg_step) { // SH 5240 /* Patch up the instruction */ 5241 func = init_function( func_IN, func_buf ); 5242 _patch_op_imm(&func_buf[0], (j & 0x1F), 11, 5); 5243 patch_op_imm(&func_buf[0], ((j>>5)&1), 1, 1); 5244 5245 r14 = iargs[i]; 5246 5247 SET_CR_XER_ZERO; 5248 (*func)(); 5249 GET_CR_XER(flags,xer); 5250 res = r17; 5251 5252 printf("%s %016llx, %2d => %016llx (%08x %08x)\n", 5253 name, iargs[i], j, res, flags, xer); 5254 } 5255 if (verbose) printf("\n"); 5256 } 5257 } 5258 #endif // #ifdef __powerpc64__ 5259 5260 5261 typedef struct special_t special_t; 5262 5263 struct special_t { 5264 const char *name; 5265 void (*test_cb)(const char* name, test_func_t func, 5266 unused uint32_t test_flags); 5267 }; 5268 5269 static void test_special (special_t *table, 5270 const char* name, test_func_t func, 5271 unused uint32_t test_flags) 5272 { 5273 const char *tmp; 5274 int i; 5275 5276 for (tmp = name; isspace(*tmp); tmp++) 5277 continue; 5278 for (i=0; table[i].name != NULL; i++) { 5279 #if 0 5280 fprintf(stderr, "look for handler for '%s' (%s)\n", name, 5281 table[i].name); 5282 #endif 5283 if (strcmp(table[i].name, tmp) == 0) { 5284 (*table[i].test_cb)(name, func, test_flags); 5285 return; 5286 } 5287 } 5288 fprintf(stderr, "ERROR: no test found for op '%s'\n", name); 5289 } 5290 5291 static special_t special_int_ops[] = { 5292 { 5293 "rlwimi", /* One register + 3 5 bits immediate arguments */ 5294 &rlwi_cb, 5295 }, 5296 { 5297 "rlwimi.", /* One register + 3 5 bits immediate arguments */ 5298 &rlwi_cb, 5299 }, 5300 { 5301 "rlwinm", /* One register + 3 5 bits immediate arguments */ 5302 &rlwi_cb, 5303 }, 5304 { 5305 "rlwinm.", /* One register + 3 5 bits immediate arguments */ 5306 &rlwi_cb, 5307 }, 5308 { 5309 "rlwnm", /* Two registers + 2 5 bits immediate arguments */ 5310 &rlwnm_cb, 5311 }, 5312 { 5313 "rlwnm.", /* Two registers + 2 5 bits immediate arguments */ 5314 &rlwnm_cb, 5315 }, 5316 { 5317 "srawi", /* One register + 1 5 bits immediate arguments */ 5318 &srawi_cb, 5319 }, 5320 { 5321 "srawi.", /* One register + 1 5 bits immediate arguments */ 5322 &srawi_cb, 5323 }, 5324 { 5325 "mcrf", /* 2 3 bits immediate arguments */ 5326 &mcrf_cb, 5327 }, 5328 #if 0 5329 { 5330 "mcrfs", /* 2 3 bits immediate arguments */ 5331 &mcrfs_cb, 5332 }, 5333 #endif 5334 { 5335 "mcrxr", /* 1 3 bits immediate argument */ 5336 &mcrxr_cb, 5337 }, 5338 { 5339 "mfcr", /* No arguments */ 5340 &mfcr_cb, 5341 }, 5342 { 5343 "mfspr", /* 1 10 bits immediate argument */ 5344 &mfspr_cb, 5345 }, 5346 #if 0 5347 { // Move from time base 5348 "mftb", /* 1 10 bits immediate arguments */ 5349 &mftb_cb, 5350 }, 5351 #endif 5352 { 5353 "mtcrf", /* One register + 1 8 bits immediate arguments */ 5354 &mtcrf_cb, 5355 }, 5356 { 5357 "mtspr", /* One register + 1 10 bits immediate arguments */ 5358 &mtspr_cb, 5359 }, 5360 #ifdef __powerpc64__ 5361 { 5362 "rldcl", /* Two registers + 1 6 bit immediate argument */ 5363 &rldc_cb, 5364 }, 5365 { 5366 "rldcl.", /* Two registers + 1 6 bit immediate argument */ 5367 &rldc_cb, 5368 }, 5369 { 5370 "rldcr", /* Two registers + 1 6 bit immediate argument */ 5371 &rldc_cb, 5372 }, 5373 { 5374 "rldcr.", /* Two registers + 1 6 bit immediate argument */ 5375 &rldc_cb, 5376 }, 5377 { 5378 "rldic", /* One register + 2 6 bit immediate arguments */ 5379 &rldi_cb, 5380 }, 5381 { 5382 "rldic.", /* One register + 2 6 bit immediate arguments */ 5383 &rldi_cb, 5384 }, 5385 { 5386 "rldicl", /* One register + 2 6 bit immediate arguments */ 5387 &rldi_cb, 5388 }, 5389 { 5390 "rldicl.", /* One register + 2 6 bit immediate arguments */ 5391 &rldi_cb, 5392 }, 5393 { 5394 "rldicr", /* One register + 2 6 bit immediate arguments */ 5395 &rldi_cb, 5396 }, 5397 { 5398 "rldicr.", /* One register + 2 6 bit immediate arguments */ 5399 &rldi_cb, 5400 }, 5401 { 5402 "rldimi", /* One register + 2 6 bit immediate arguments */ 5403 &rldi_cb, 5404 }, 5405 { 5406 "rldimi.", /* One register + 2 6 bit immediate arguments */ 5407 &rldi_cb, 5408 }, 5409 { 5410 "sradi", /* One register + 1 6 bit immediate argument */ 5411 &sradi_cb, 5412 }, 5413 { 5414 "sradi.", /* One register + 1 6 bit immediate argument */ 5415 &sradi_cb, 5416 }, 5417 #endif // #ifdef __powerpc64__ 5418 { 5419 NULL, 5420 NULL, 5421 }, 5422 }; 5423 5424 static void test_int_special (const char* name, test_func_t func, 5425 uint32_t test_flags) 5426 { 5427 test_special(special_int_ops, name, func, test_flags); 5428 } 5429 5430 5431 static void test_int_ld_one_reg_imm16 (const char* name, 5432 test_func_t func_IN, 5433 unused uint32_t test_flags) 5434 { 5435 volatile test_func_t func; 5436 uint32_t* func_buf = get_rwx_area(); 5437 volatile HWord_t res, base; 5438 volatile uint32_t flags, xer; 5439 int i, offs, is_lwa=0; 5440 5441 #ifdef __powerpc64__ 5442 is_lwa = strstr(name, "lwa") != NULL; 5443 #endif 5444 5445 // +ve d 5446 base = (HWord_t)&iargs[0]; 5447 for (i=0; i<nb_iargs; i++) { 5448 offs = i * sizeof(HWord_t); 5449 5450 /* Patch up the instruction */ 5451 func = init_function( func_IN, func_buf ); 5452 if (is_lwa) 5453 patch_op_imm(&func_buf[0], offs>>2, 2, 14); 5454 else 5455 patch_op_imm16(&func_buf[0], offs); 5456 5457 r14 = base; 5458 5459 SET_CR_XER_ZERO; 5460 (*func)(); 5461 GET_CR_XER(flags,xer); 5462 res = r17; 5463 5464 #ifndef __powerpc64__ 5465 printf("%s %2d, (%08x) => %08x, %2d (%08x %08x)\n", 5466 #else 5467 printf("%s %3d, (%016llx) => %016llx, %3lld (%08x %08x)\n", 5468 #endif 5469 name, offs, iargs[i], res, r14-base, flags, xer); 5470 } 5471 if (verbose) printf("\n"); 5472 5473 // -ve d 5474 base = (HWord_t)&iargs[nb_iargs-1]; 5475 for (i = -nb_iargs+1; i<=0; i++) { 5476 offs = i * sizeof(HWord_t); 5477 5478 /* Patch up the instruction */ 5479 func = init_function( func, func_buf ); 5480 patch_op_imm16(&func_buf[0], offs); 5481 5482 r14 = base; 5483 5484 SET_CR_XER_ZERO; 5485 (*func)(); 5486 GET_CR_XER(flags,xer); 5487 res = r17; 5488 5489 #ifndef __powerpc64__ 5490 printf("%s %2d, (%08x) => %08x, %2d (%08x %08x)\n", 5491 #else 5492 printf("%s %3d, (%016llx) => %016llx, %3lld (%08x %08x)\n", 5493 #endif 5494 name, offs, iargs[nb_iargs-1+i], res, r14-base, flags, xer); 5495 } 5496 } 5497 5498 static void test_int_ld_two_regs (const char* name, 5499 test_func_t func, 5500 unused uint32_t test_flags) 5501 { 5502 volatile HWord_t res, base; 5503 volatile uint32_t flags, xer; 5504 int i, offs; 5505 5506 // +ve d 5507 base = (HWord_t)&iargs[0]; 5508 for (i=0; i<nb_iargs; i++) { 5509 offs = i * sizeof(HWord_t); 5510 r14 = base; 5511 r15 = offs; 5512 5513 SET_CR_XER_ZERO; 5514 (*func)(); 5515 GET_CR_XER(flags,xer); 5516 res = r17; 5517 5518 #ifndef __powerpc64__ 5519 printf("%s %d (%08x) => %08x, %d (%08x %08x)\n", 5520 #else 5521 printf("%s %3d, (%016llx) => %016llx, %2lld (%08x %08x)\n", 5522 #endif 5523 name, offs, iargs[i], res, r14-base, flags, xer); 5524 } 5525 } 5526 5527 static void test_int_st_two_regs_imm16 (const char* name, 5528 test_func_t func_IN, 5529 unused uint32_t test_flags) 5530 { 5531 volatile test_func_t func; 5532 uint32_t* func_buf = get_rwx_area(); 5533 volatile uint32_t flags, xer; 5534 int i, offs, k; 5535 HWord_t *iargs_priv, base; 5536 5537 // private iargs table to store to 5538 iargs_priv = malloc(nb_iargs * sizeof(HWord_t)); 5539 5540 // +ve d 5541 base = (HWord_t)&iargs_priv[0]; 5542 for (i=0; i<nb_iargs; i++) { 5543 for (k=0; k<nb_iargs; k++) // clear array 5544 iargs_priv[k] = 0; 5545 5546 offs = i * sizeof(HWord_t); 5547 5548 /* Patch up the instruction */ 5549 func = init_function( func_IN, func_buf ); 5550 patch_op_imm16(&func_buf[0], offs); 5551 5552 r14 = iargs[i]; // read from iargs 5553 r15 = base; // store to r15 + offs 5554 5555 SET_CR_XER_ZERO; 5556 (*func)(); 5557 GET_CR_XER(flags,xer); 5558 5559 #ifndef __powerpc64__ 5560 printf("%s %08x, %2d => %08x, %2d (%08x %08x)\n", 5561 #else 5562 printf("%s %016llx, %3d => %016llx, %3lld (%08x %08x)\n", 5563 #endif 5564 name, iargs[i], offs, iargs_priv[i], r15-base, flags, xer); 5565 } 5566 if (verbose) printf("\n"); 5567 5568 // -ve d 5569 base = (HWord_t)&iargs_priv[nb_iargs-1]; 5570 for (i = -nb_iargs+1; i<=0; i++) { 5571 for (k=0; k<nb_iargs; k++) // clear array 5572 iargs_priv[k] = 0; 5573 5574 offs = i * sizeof(HWord_t); 5575 5576 /* Patch up the instruction */ 5577 func = init_function( func, func_buf ); 5578 patch_op_imm16(&func_buf[0], offs); 5579 5580 r14 = iargs[nb_iargs-1+i]; // read from iargs 5581 r15 = base; // store to r15 + offs 5582 5583 SET_CR_XER_ZERO; 5584 (*func)(); 5585 GET_CR_XER(flags,xer); 5586 5587 #ifndef __powerpc64__ 5588 printf("%s %08x, %2d => %08x, %2d (%08x %08x)\n", 5589 #else 5590 printf("%s %016llx, %3d => %016llx, %3lld (%08x %08x)\n", 5591 #endif 5592 name, iargs[nb_iargs-1+i], offs, iargs_priv[nb_iargs-1+i], 5593 r15-base, flags, xer); 5594 } 5595 free(iargs_priv); 5596 } 5597 5598 static void test_int_st_three_regs (const char* name, 5599 test_func_t func, 5600 unused uint32_t test_flags) 5601 { 5602 volatile uint32_t flags, xer; 5603 int i, offs, k; 5604 HWord_t *iargs_priv, base; 5605 5606 // private iargs table to store to 5607 iargs_priv = malloc(nb_iargs * sizeof(HWord_t)); 5608 5609 base = (HWord_t)&iargs_priv[0]; 5610 for (i=0; i<nb_iargs; i++) { 5611 for (k=0; k<nb_iargs; k++) // clear array 5612 iargs_priv[k] = 0; 5613 5614 offs = i * sizeof(HWord_t); 5615 r14 = iargs[i]; // read from iargs 5616 r15 = base; // store to r15 + offs 5617 r16 = offs; 5618 5619 SET_CR_XER_ZERO; 5620 (*func)(); 5621 GET_CR_XER(flags,xer); 5622 5623 #ifndef __powerpc64__ 5624 printf("%s %08x, %d => %08x, %d (%08x %08x)\n", 5625 #else 5626 printf("%s %016llx, %3d => %016llx, %2lld (%08x %08x)\n", 5627 #endif 5628 name, iargs[i], offs, iargs_priv[i], r15-base, flags, xer); 5629 } 5630 free(iargs_priv); 5631 } 5632 5633 5634 /* Used in do_tests, indexed by flags->nb_args 5635 Elements correspond to enum test_flags::num args 5636 */ 5637 static test_loop_t int_loops[] = { 5638 &test_int_one_arg, 5639 &test_int_two_args, 5640 &test_int_three_args, 5641 &test_int_two_args, 5642 &test_int_one_reg_imm16, 5643 &test_int_one_reg_imm16, 5644 &test_int_special, 5645 &test_int_ld_one_reg_imm16, 5646 &test_int_ld_two_regs, 5647 &test_int_st_two_regs_imm16, 5648 &test_int_st_three_regs, 5649 }; 5650 5651 #if !defined (NO_FLOAT) 5652 static void test_float_three_args (const char* name, test_func_t func, 5653 unused uint32_t test_flags) 5654 { 5655 double res; 5656 uint64_t u0, u1, u2, ur; 5657 volatile uint32_t flags; 5658 int i, j, k; 5659 5660 /* Note: using nb_normal_fargs: 5661 - not testing special values for these insns 5662 */ 5663 5664 for (i=0; i<nb_normal_fargs; i+=3) { 5665 for (j=0; j<nb_normal_fargs; j+=5) { 5666 for (k=0; k<nb_normal_fargs; k+=7) { 5667 u0 = *(uint64_t *)(&fargs[i]); 5668 u1 = *(uint64_t *)(&fargs[j]); 5669 u2 = *(uint64_t *)(&fargs[k]); 5670 f14 = fargs[i]; 5671 f15 = fargs[j]; 5672 f16 = fargs[k]; 5673 5674 SET_FPSCR_ZERO; 5675 SET_CR_XER_ZERO; 5676 (*func)(); 5677 GET_CR(flags); 5678 res = f17; 5679 ur = *(uint64_t *)(&res); 5680 5681 /* Note: zapping the bottom byte of the result, 5682 as vex's accuracy isn't perfect */ 5683 ur &= 0xFFFFFFFFFFFFFF00ULL; 5684 5685 #ifndef __powerpc64__ 5686 printf("%s %016llx, %016llx, %016llx => %016llx", 5687 #else 5688 printf("%s %016llx, %016llx, %016llx => %016llx", 5689 #endif 5690 name, u0, u1, u2, ur); 5691 #if defined TEST_FLOAT_FLAGS 5692 printf(" (%08x)", flags); 5693 #endif 5694 printf("\n"); 5695 } 5696 if (verbose) printf("\n"); 5697 } 5698 } 5699 } 5700 5701 static void test_float_two_args (const char* name, test_func_t func, 5702 unused uint32_t test_flags) 5703 { 5704 double res; 5705 uint64_t u0, u1, ur; 5706 volatile uint32_t flags; 5707 int i, j; 5708 5709 for (i=0; i<nb_fargs; i+=3) { 5710 for (j=0; j<nb_fargs; j+=5) { 5711 u0 = *(uint64_t *)(&fargs[i]); 5712 u1 = *(uint64_t *)(&fargs[j]); 5713 f14 = fargs[i]; 5714 f15 = fargs[j]; 5715 5716 SET_FPSCR_ZERO; 5717 SET_CR_XER_ZERO; 5718 (*func)(); 5719 GET_CR(flags); 5720 res = f17; 5721 ur = *(uint64_t *)(&res); 5722 5723 #ifndef __powerpc64__ 5724 printf("%s %016llx, %016llx => %016llx", 5725 #else 5726 printf("%s %016llx, %016llx => %016llx", 5727 #endif 5728 name, u0, u1, ur); 5729 #if defined TEST_FLOAT_FLAGS 5730 printf(" (%08x)", flags); 5731 #endif 5732 printf("\n"); 5733 } 5734 if (verbose) printf("\n"); 5735 } 5736 } 5737 5738 static void test_float_one_arg (const char* name, test_func_t func, 5739 unused uint32_t test_flags) 5740 { 5741 double res; 5742 uint64_t u0, ur; 5743 volatile uint32_t flags; 5744 int i; 5745 unsigned zap_hi_32bits, zap_lo_44bits, zap_lo_47bits; 5746 5747 /* if we're testing fctiw or fctiwz, zap the hi 32bits, 5748 as they're undefined */ 5749 zap_hi_32bits = strstr(name, " fctiw") != NULL ? 1 : 0; 5750 zap_lo_44bits = strstr(name, " fres") != NULL ? 1 : 0; 5751 zap_lo_47bits = strstr(name, " frsqrte") != NULL ? 1 : 0; 5752 5753 assert(zap_hi_32bits + zap_lo_44bits + zap_lo_47bits <= 1); 5754 5755 for (i=0; i<nb_fargs; i++) { 5756 u0 = *(uint64_t *)(&fargs[i]); 5757 f14 = fargs[i]; 5758 5759 SET_FPSCR_ZERO; 5760 SET_CR_XER_ZERO; 5761 (*func)(); 5762 GET_CR(flags); 5763 res = f17; 5764 ur = *(uint64_t *)(&res); 5765 5766 if (strstr(name, " frsqrte") != NULL) 5767 /* The 32-bit frsqrte instruction is the Floatig Reciprical Square 5768 * Root Estimate instruction. The precision of the estimate will 5769 * vary from Proceesor implementation. The approximation varies in 5770 * bottom two bytes of the 32-bit result. 5771 */ 5772 ur &= 0xFFFF000000000000ULL; 5773 5774 if (zap_hi_32bits) 5775 ur &= 0x00000000FFFFFFFFULL; 5776 if (zap_lo_44bits) 5777 ur &= 0xFFFFF00000000000ULL; 5778 if (zap_lo_47bits) 5779 ur &= 0xFFFF800000000000ULL; 5780 5781 #ifndef __powerpc64__ 5782 printf("%s %016llx => %016llx", 5783 #else 5784 printf("%s %016llx => %016llx", 5785 #endif 5786 name, u0, ur); 5787 #if defined TEST_FLOAT_FLAGS 5788 printf(" (%08x)", flags); 5789 #endif 5790 printf("\n"); 5791 } 5792 } 5793 5794 /* Special test cases for: 5795 * mffs 5796 * mtfsb0 5797 * mtfsb1 5798 */ 5799 static special_t special_float_ops[] = { 5800 #if 0 5801 { 5802 "mffs", /* One 5 bits immediate argument */ 5803 &mffs_cb, 5804 }, 5805 { 5806 "mffs.", /* One 5 bits immediate argument */ 5807 &mffs_cb, 5808 }, 5809 { 5810 "mtfsb0", /* One 5 bits immediate argument */ 5811 &mffs_cb, 5812 }, 5813 { 5814 "mtfsb0.", /* One 5 bits immediate argument */ 5815 &mffs_cb, 5816 }, 5817 { 5818 "mtfsb1", /* One 5 bits immediate argument */ 5819 &mffs_cb, 5820 }, 5821 { 5822 "mtfsb1.", /* One 5 bits immediate argument */ 5823 &mffs_cb, 5824 }, 5825 { 5826 "mtfsf", /* One register + 1 8 bits immediate argument */ 5827 &mtfsf_cb, 5828 }, 5829 { 5830 "mtfsf.", /* One register + 1 8 bits immediate argument */ 5831 &mtfsf_cb, 5832 }, 5833 { 5834 "mtfsfi", /* One 5 bits argument + 1 5 bits argument */ 5835 &mtfsfi_cb, 5836 }, 5837 { 5838 "mtfsfi.", /* One 5 bits argument + 1 5 bits argument */ 5839 &mtfsfi_cb, 5840 }, 5841 #endif 5842 { 5843 NULL, 5844 NULL, 5845 }, 5846 }; 5847 5848 static void test_float_special (const char* name, test_func_t func, 5849 uint32_t test_flags) 5850 { 5851 test_special(special_float_ops, name, func, test_flags); 5852 } 5853 5854 5855 static void test_float_ld_one_reg_imm16 (const char* name, 5856 test_func_t func_IN, 5857 unused uint32_t test_flags) 5858 { 5859 volatile test_func_t func; 5860 uint32_t* func_buf = get_rwx_area(); 5861 uint32_t base; 5862 volatile uint32_t flags, xer; 5863 volatile double src, res; 5864 int i, offs; 5865 5866 /* offset within [1-nb_fargs:nb_fargs] */ 5867 for (i=1-nb_fargs; i<nb_fargs; i++) { 5868 offs = i * 8; // offset = i * sizeof(double) 5869 if (i < 0) { 5870 src = fargs[nb_fargs-1 + i]; 5871 base = (HWord_t)&fargs[nb_fargs-1]; 5872 } else { 5873 src = fargs[i]; 5874 base = (HWord_t)&fargs[0]; 5875 } 5876 5877 /* Patch up the instruction */ 5878 func = init_function( func_IN, func_buf ); 5879 patch_op_imm16(&func_buf[0], offs); 5880 5881 // load from fargs[idx] => r14 + offs 5882 r14 = base; 5883 5884 SET_CR_XER_ZERO; 5885 (*func)(); 5886 GET_CR_XER(flags,xer); 5887 res = f17; 5888 5889 #ifndef __powerpc64__ 5890 printf("%s %016llx, %4d => %016llx, %4d", 5891 #else 5892 printf("%s %016llx, %4d => %016llx, %4lld", 5893 #endif 5894 name, double_to_bits(src), offs, 5895 double_to_bits(res), r14-base); 5896 #if defined TEST_FLOAT_FLAGS 5897 printf(" (%08x %08x)", flags, xer); 5898 #endif 5899 printf("\n"); 5900 } 5901 if (verbose) printf("\n"); 5902 } 5903 5904 static void test_float_ld_two_regs (const char* name, 5905 test_func_t func, 5906 unused uint32_t test_flags) 5907 { 5908 volatile HWord_t base; 5909 volatile uint32_t flags, xer; 5910 volatile double src, res; 5911 int i, offs; 5912 5913 /* offset within [1-nb_fargs:nb_fargs] */ 5914 for (i=1-nb_fargs; i<nb_fargs; i++) { 5915 offs = i * 8; // offset = i * sizeof(double) 5916 if (i < 0) { // base reg = start of array 5917 src = fargs[nb_fargs-1 + i]; 5918 base = (HWord_t)&fargs[nb_fargs-1]; 5919 } else { 5920 src = fargs[i]; 5921 base = (HWord_t)&fargs[0]; 5922 } 5923 5924 r14 = base; 5925 r15 = offs; 5926 5927 SET_CR_XER_ZERO; 5928 (*func)(); 5929 GET_CR_XER(flags,xer); 5930 res = f17; 5931 5932 #ifndef __powerpc64__ 5933 printf("%s %016llx, %4d => %016llx, %4d", 5934 #else 5935 printf("%s %016llx, %4lld => %016llx, %4lld", 5936 #endif 5937 name, double_to_bits(src), r15/*offs*/, 5938 double_to_bits(res), r14-base); 5939 #if defined TEST_FLOAT_FLAGS 5940 printf(" (%08x %08x)", flags, xer); 5941 #endif 5942 printf("\n"); 5943 } 5944 } 5945 5946 static void test_float_st_two_regs_imm16 (const char* name, 5947 test_func_t func_IN, 5948 unused uint32_t test_flags) 5949 { 5950 volatile test_func_t func; 5951 uint32_t* func_buf = get_rwx_area(); 5952 HWord_t base; 5953 volatile uint32_t flags, xer; 5954 double src, *p_dst; 5955 int i, offs; 5956 double *fargs_priv; 5957 int nb_tmp_fargs = nb_fargs; 5958 5959 5960 /* if we're storing an fp single-precision, don't want nans 5961 - the vex implementation doesn't like them (yet) 5962 Note: This is actually a bigger problem: the vex implementation 5963 rounds these insns twice. This leads to many rounding errors. 5964 For the small fargs set, however, this doesn't show up. 5965 */ 5966 if (strstr(name, "stfs") != NULL) 5967 nb_tmp_fargs = nb_normal_fargs; 5968 5969 5970 // private fargs table to store to 5971 fargs_priv = malloc(nb_tmp_fargs * sizeof(double)); 5972 5973 /* offset within [1-nb_tmp_fargs:nb_tmp_fargs] */ 5974 for (i=1-nb_tmp_fargs; i<nb_tmp_fargs; i++) { 5975 offs = i * 8; // offset = i * sizeof(double) 5976 if (i < 0) { 5977 src = fargs [nb_tmp_fargs-1 + i]; 5978 p_dst = &fargs_priv[nb_tmp_fargs-1 + i]; 5979 base = (HWord_t)&fargs_priv[nb_tmp_fargs-1]; 5980 } else { 5981 src = fargs [i]; 5982 p_dst = &fargs_priv[i]; 5983 base = (HWord_t)&fargs_priv[0]; 5984 } 5985 *p_dst = 0; // clear dst 5986 5987 /* Patch up the instruction */ 5988 func = init_function( func_IN, func_buf ); 5989 patch_op_imm16(&func_buf[0], offs); 5990 5991 // read from fargs[idx] => f14 5992 // store to fargs_priv[idx] => r15 + offs 5993 f14 = src; 5994 r15 = base; 5995 5996 SET_CR_XER_ZERO; 5997 (*func)(); 5998 GET_CR_XER(flags,xer); 5999 6000 #ifndef __powerpc64__ 6001 printf("%s %016llx, %4d => %016llx, %4d", 6002 #else 6003 printf("%s %016llx, %4d => %016llx, %4lld", 6004 #endif 6005 name, double_to_bits(src), offs, 6006 double_to_bits(*p_dst), r15-base); 6007 #if defined TEST_FLOAT_FLAGS 6008 printf(" (%08x %08x)", flags, xer); 6009 #endif 6010 printf("\n"); 6011 } 6012 free(fargs_priv); 6013 } 6014 6015 static void test_float_st_three_regs (const char* name, 6016 test_func_t func, 6017 unused uint32_t test_flags) 6018 { 6019 volatile HWord_t base; 6020 volatile uint32_t flags, xer; 6021 double src, *p_dst; 6022 int i, offs; 6023 double *fargs_priv; 6024 int nb_tmp_fargs = nb_fargs; 6025 6026 6027 /* if we're storing an fp single-precision, don't want nans 6028 - the vex implementation doesn't like them (yet) 6029 Note: This is actually a bigger problem: the vex implementation 6030 rounds these insns twice. This leads to many rounding errors. 6031 For the small fargs set, however, this doesn't show up. 6032 */ 6033 if (strstr(name, "stfs") != NULL) // stfs(u)(x) 6034 nb_tmp_fargs = nb_normal_fargs; 6035 6036 6037 // private fargs table to store to 6038 fargs_priv = malloc(nb_tmp_fargs * sizeof(double)); 6039 6040 // /* offset within [1-nb_tmp_fargs:nb_tmp_fargs] */ 6041 // for (i=1-nb_tmp_fargs; i<nb_tmp_fargs; i++) { 6042 for (i=0; i<nb_tmp_fargs; i++) { 6043 offs = i * 8; // offset = i * sizeof(double) 6044 if (i < 0) { 6045 src = fargs [nb_tmp_fargs-1 + i]; 6046 p_dst = &fargs_priv[nb_tmp_fargs-1 + i]; 6047 base = (HWord_t)&fargs_priv[nb_tmp_fargs-1]; 6048 } else { 6049 src = fargs [i]; 6050 p_dst = &fargs_priv[i]; 6051 base = (HWord_t)&fargs_priv[0]; 6052 } 6053 *p_dst = 0; // clear dst 6054 6055 f14 = src; // read from fargs 6056 r15 = base; // store to r15 + offs 6057 r16 = offs; 6058 6059 SET_CR_XER_ZERO; 6060 (*func)(); 6061 GET_CR_XER(flags,xer); 6062 6063 #ifndef __powerpc64__ 6064 printf("%s %016llx, %4d => %016llx, %4d", 6065 #else 6066 printf("%s %016llx, %4lld => %016llx, %4lld", 6067 #endif 6068 name, double_to_bits(src), r16/*offs*/, 6069 double_to_bits(*p_dst), r15-base); 6070 #if defined TEST_FLOAT_FLAGS 6071 printf(" (%08x %08x)", flags, xer); 6072 #endif 6073 printf("\n"); 6074 6075 6076 #if 0 6077 // print double precision result 6078 #ifndef __powerpc64__ 6079 printf("%s %016llx (%014e), %4d => %016llx (%014e), %08x (%08x %08x)\n", 6080 #else 6081 printf("%s %016llx (%014e), %4d => %016llx (%014e), %08x (%08x %08x)\n", 6082 #endif 6083 name, double_to_bits(src), src, offs, 6084 double_to_bits(*p_dst), *p_dst, r15, flags, xer); 6085 6086 // print single precision result 6087 #ifndef __powerpc64__ 6088 printf("%s %016llx (%014e), %4d => %08x (%f), %08x (%08x %08x)\n", 6089 #else 6090 printf("%s %016llx (%014e), %4d => %08x (%f), %08x (%08x %08x)\n", 6091 #endif 6092 name, double_to_bits(src), src, offs, 6093 (uint32_t)(double_to_bits(*p_dst) >> 32), 6094 bits_to_float( (uint32_t)(double_to_bits(*p_dst) >> 32) ), 6095 r15, flags, xer); 6096 #endif 6097 } 6098 free(fargs_priv); 6099 } 6100 6101 6102 /* Used in do_tests, indexed by flags->nb_args 6103 Elements correspond to enum test_flags::num args 6104 */ 6105 static test_loop_t float_loops[] = { 6106 &test_float_one_arg, 6107 &test_float_two_args, 6108 &test_float_three_args, 6109 &test_float_two_args, 6110 NULL, 6111 NULL, 6112 &test_float_special, 6113 &test_float_ld_one_reg_imm16, 6114 &test_float_ld_two_regs, 6115 &test_float_st_two_regs_imm16, 6116 &test_float_st_three_regs, 6117 }; 6118 #endif /* !defined (NO_FLOAT) */ 6119 6120 6121 #if defined (HAS_ALTIVEC) 6122 6123 /* Ref: vector insns to test setting CR, VSCR: 6124 volatile vector unsigned int v1 = 6125 // (vector unsigned int){ 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }; 6126 (vector unsigned int){ 0x80808080,0x80808080,0x80808080,0x80808080 }; 6127 volatile vector unsigned int v2 = 6128 // (vector unsigned int){ 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF }; 6129 (vector unsigned int){ 0x01010101,0x01010101,0x01010101,0x01010101 }; 6130 //__asm__ __volatile__ ("vcmpequw. 31,%0,%1" : : "v" (v1), "v" (v2)); // sets CR[6] 6131 //__asm__ __volatile__ ("vpkswss 31,%0,%1" : : "v" (v1), "v" (v2)); // sets VSCR[SAT] 6132 __asm__ __volatile__ ("vsubsbs 31,%0,%1" : : "v" (v1), "v" (v2)); // sets VSCR[SAT] 6133 */ 6134 6135 //#define DEFAULT_VSCR 0x00010000 6136 #define DEFAULT_VSCR 0x0 6137 6138 static void test_av_int_one_arg (const char* name, test_func_t func, 6139 unused uint32_t test_flags) 6140 { 6141 volatile uint32_t flags, tmpcr; 6142 volatile vector unsigned int tmpvscr; 6143 volatile vector unsigned int vec_in, vec_out, vscr; 6144 unsigned int *src, *dst; 6145 int i; 6146 #if defined TEST_VSCR_SAT 6147 unsigned int* p_vscr; 6148 #endif 6149 6150 for (i=0; i<nb_viargs; i++) { 6151 /* Save flags */ 6152 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6153 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6154 6155 vec_in = (vector unsigned int)viargs[i]; 6156 vec_out = (vector unsigned int){ 0,0,0,0 }; 6157 6158 // reset VSCR and CR 6159 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6160 flags = 0; 6161 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6162 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6163 6164 // load input -> r14 6165 __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in)); 6166 6167 // do stuff 6168 (*func)(); 6169 6170 // retrieve output <- r17 6171 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 6172 6173 // get CR,VSCR flags 6174 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6175 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6176 6177 /* Restore flags */ 6178 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6179 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6180 6181 src = (unsigned int*)&vec_in; 6182 dst = (unsigned int*)&vec_out; 6183 6184 printf("%s: %08x %08x %08x %08x\n", name, 6185 src[0], src[1], src[2], src[3]); 6186 printf("%s: => %08x %08x %08x %08x ", name, 6187 dst[0], dst[1], dst[2], dst[3]); 6188 #if defined TEST_VSCR_SAT 6189 p_vscr = (unsigned int*)𝓋 6190 printf("(%08x, %08x)\n", flags, p_vscr[3]); 6191 #else 6192 printf("(%08x)\n", flags); 6193 #endif 6194 } 6195 } 6196 6197 static void test_av_int_two_args (const char* name, test_func_t func, 6198 unused uint32_t test_flags) 6199 { 6200 volatile uint32_t flags, tmpcr; 6201 volatile vector unsigned int tmpvscr; 6202 volatile vector unsigned int vec_in1, vec_in2, vec_out, vscr; 6203 unsigned int *src1, *src2, *dst; 6204 int i,j; 6205 #if defined TEST_VSCR_SAT 6206 unsigned int* p_vscr; 6207 #endif 6208 6209 for (i=0; i<nb_viargs; i++) { 6210 vec_in1 = (vector unsigned int)viargs[i]; 6211 for (j=0; j<nb_viargs; j++) { 6212 vec_in2 = (vector unsigned int)viargs[j]; 6213 vec_out = (vector unsigned int){ 0,0,0,0 }; 6214 6215 /* Save flags */ 6216 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6217 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6218 6219 // reset VSCR and CR 6220 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6221 flags = 0; 6222 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6223 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6224 6225 // load inputs -> r14,r15 6226 __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1)); 6227 __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2)); 6228 6229 // do stuff 6230 (*func)(); 6231 6232 // retrieve output <- r17 6233 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 6234 6235 // get CR,VSCR flags 6236 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6237 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6238 6239 /* Restore flags */ 6240 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6241 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6242 6243 src1 = (unsigned int*)&vec_in1; 6244 src2 = (unsigned int*)&vec_in2; 6245 dst = (unsigned int*)&vec_out; 6246 6247 printf("%s: ", name); 6248 printf("%08x%08x%08x%08x, ", src1[0], src1[1], src1[2], src1[3]); 6249 printf("%08x%08x%08x%08x\n", src2[0], src2[1], src2[2], src2[3]); 6250 printf("%s: => %08x %08x %08x %08x ", name, 6251 dst[0], dst[1], dst[2], dst[3]); 6252 #if defined TEST_VSCR_SAT 6253 p_vscr = (unsigned int*)𝓋 6254 printf("(%08x, %08x)\n", flags, p_vscr[3]); 6255 #else 6256 printf("(%08x)\n", flags); 6257 #endif 6258 } 6259 if (verbose) printf("\n"); 6260 } 6261 } 6262 6263 static void test_av_int_three_args (const char* name, test_func_t func, 6264 unused uint32_t test_flags) 6265 { 6266 volatile uint32_t flags, tmpcr; 6267 volatile vector unsigned int tmpvscr; 6268 volatile vector unsigned int vec_in1, vec_in2, vec_in3, vec_out, vscr; 6269 unsigned int *src1, *src2, *src3, *dst; 6270 int i,j,k; 6271 #if defined TEST_VSCR_SAT 6272 unsigned int* p_vscr; 6273 #endif 6274 6275 for (i=0; i<nb_viargs; i++) { 6276 vec_in1 = (vector unsigned int)viargs[i]; 6277 for (j=0; j<nb_viargs; j++) { 6278 vec_in2 = (vector unsigned int)viargs[j]; 6279 for (k=0; k<nb_viargs; k++) { 6280 vec_in3 = (vector unsigned int)viargs[k]; 6281 vec_out = (vector unsigned int){ 0,0,0,0 }; 6282 6283 /* Save flags */ 6284 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6285 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6286 6287 // reset VSCR and CR 6288 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6289 flags = 0; 6290 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6291 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6292 6293 // load inputs -> r14,r15,r16 6294 __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1)); 6295 __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2)); 6296 __asm__ __volatile__ ("vor 16,%0,%0" : : "v" (vec_in3)); 6297 6298 // do stuff 6299 (*func)(); 6300 6301 // retrieve output <- r17 6302 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 6303 6304 // get CR,VSCR flags 6305 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6306 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6307 6308 /* Restore flags */ 6309 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6310 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6311 6312 src1 = (unsigned int*)&vec_in1; 6313 src2 = (unsigned int*)&vec_in2; 6314 src3 = (unsigned int*)&vec_in3; 6315 dst = (unsigned int*)&vec_out; 6316 6317 printf("%s: %08x%08x%08x%08x, %08x%08x%08x%08x, %08x%08x%08x%08x\n", name, 6318 src1[0], src1[1], src1[2], src1[3], 6319 src2[0], src2[1], src2[2], src2[3], 6320 src3[0], src3[1], src3[2], src3[3]); 6321 6322 printf("%s: => %08x%08x%08x%08x ", name, 6323 dst[0], dst[1], dst[2], dst[3]); 6324 #if defined TEST_VSCR_SAT 6325 p_vscr = (unsigned int*)𝓋 6326 printf("(%08x, %08x)\n", flags, p_vscr[3]); 6327 #else 6328 printf("(%08x)\n", flags); 6329 #endif 6330 } 6331 if (verbose) printf("\n"); 6332 } 6333 } 6334 } 6335 6336 6337 static void vs128_cb (const char* name, test_func_t func, 6338 unused uint32_t test_flags) 6339 { 6340 volatile uint32_t flags, tmpcr; 6341 volatile vector unsigned int tmpvscr; 6342 volatile vector unsigned char vec_shft; 6343 volatile vector unsigned int vec_in1, vec_out, vscr; 6344 unsigned int *src1, *src2, *dst; 6345 int i,j; 6346 #if defined TEST_VSCR_SAT 6347 unsigned int* p_vscr; 6348 #endif 6349 6350 for (i=0; i<nb_viargs; i++) { 6351 vec_in1 = (vector unsigned int)viargs[i]; 6352 for (j=0; j<8; j++) { 6353 /* low-order 3bits of every byte must be the same for the shift vector */ 6354 vec_shft = (vector unsigned char) { j,j,j,j, j,j,j,j, j,j,j,j, j,j,j,j }; 6355 vec_out = (vector unsigned int){ 0,0,0,0 }; 6356 6357 /* Save flags */ 6358 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6359 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6360 6361 // reset VSCR and CR 6362 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6363 flags = 0; 6364 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6365 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6366 6367 // load inputs -> r14,r15 6368 __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1)); 6369 __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_shft)); 6370 6371 // do stuff 6372 (*func)(); 6373 6374 // retrieve output <- r17 6375 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 6376 6377 // get CR,VSCR flags 6378 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6379 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6380 6381 /* Restore flags */ 6382 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6383 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6384 6385 src1 = (unsigned int*)&vec_in1; 6386 src2 = (unsigned int*)&vec_shft; 6387 dst = (unsigned int*)&vec_out; 6388 6389 printf("%s: ", name); 6390 printf("%08x%08x%08x%08x, ", src1[0], src1[1], src1[2], src1[3]); 6391 printf("%08x%08x%08x%08x\n", src2[0], src2[1], src2[2], src2[3]); 6392 6393 printf("%s: => %08x %08x %08x %08x ", name, 6394 dst[0], dst[1], dst[2], dst[3]); 6395 #if defined TEST_VSCR_SAT 6396 p_vscr = (unsigned int*)𝓋 6397 printf("(%08x, %08x)\n", flags, p_vscr[3]); 6398 #else 6399 printf("(%08x)\n", flags); 6400 #endif 6401 } 6402 if (verbose) printf("\n"); 6403 } 6404 } 6405 6406 static void vsplt_cb (const char* name, test_func_t func_IN, 6407 unused uint32_t test_flags) 6408 { 6409 volatile test_func_t func; 6410 uint32_t* func_buf = get_rwx_area(); 6411 volatile uint32_t flags, tmpcr; 6412 volatile vector unsigned int tmpvscr; 6413 volatile vector unsigned int vec_in1, vec_out, vscr; 6414 unsigned int *src1, *dst; 6415 int i,j; 6416 #if defined TEST_VSCR_SAT 6417 unsigned int* p_vscr; 6418 #endif 6419 6420 for (i=0; i<nb_viargs; i++) { 6421 vec_in1 = (vector unsigned int)viargs[i]; 6422 6423 for (j=0; j<16; j+=3) { 6424 vec_out = (vector unsigned int){ 0,0,0,0 }; 6425 6426 /* Patch up the instruction */ 6427 func = init_function( func_IN, func_buf ); 6428 patch_op_imm(&func_buf[0], j, 16, 5); 6429 6430 /* Save flags */ 6431 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6432 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6433 6434 // reset VSCR and CR 6435 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6436 flags = 0; 6437 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6438 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6439 6440 // load input -> r14 6441 __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1)); 6442 6443 // do stuff 6444 (*func)(); 6445 6446 // retrieve output <- r17 6447 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 6448 6449 // get CR,VSCR flags 6450 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6451 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6452 6453 /* Restore flags */ 6454 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6455 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6456 6457 src1 = (unsigned int*)&vec_in1; 6458 dst = (unsigned int*)&vec_out; 6459 6460 printf("%s: ", name); 6461 printf("%08x %08x %08x %08x, %u\n", src1[0], src1[1], src1[2], src1[3], j); 6462 6463 printf("%s: => %08x %08x %08x %08x ", name, 6464 dst[0], dst[1], dst[2], dst[3]); 6465 #if defined TEST_VSCR_SAT 6466 p_vscr = (unsigned int*)𝓋 6467 printf("(%08x, %08x)\n", flags, p_vscr[3]); 6468 #else 6469 printf("(%08x)\n", flags); 6470 #endif 6471 } 6472 if (verbose) printf("\n"); 6473 } 6474 } 6475 6476 static void vspltis_cb (const char* name, test_func_t func_IN, 6477 unused uint32_t test_flags) 6478 { 6479 volatile test_func_t func; 6480 uint32_t* func_buf = get_rwx_area(); 6481 volatile uint32_t flags, tmpcr; 6482 volatile vector unsigned int tmpvscr; 6483 volatile vector unsigned int vec_out, vscr; 6484 unsigned int *dst; 6485 int i; 6486 #if defined TEST_VSCR_SAT 6487 unsigned int* p_vscr; 6488 #endif 6489 6490 for (i=0; i<32; i++) { 6491 vec_out = (vector unsigned int){ 0,0,0,0 }; 6492 6493 /* Patch up the instruction */ 6494 func = init_function( func_IN, func_buf ); 6495 patch_op_imm(&func_buf[0], i, 16, 5); 6496 6497 /* Save flags */ 6498 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6499 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6500 6501 // reset VSCR and CR 6502 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6503 flags = 0; 6504 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6505 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6506 6507 // do stuff 6508 (*func)(); 6509 6510 // retrieve output <- r17 6511 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 6512 6513 // get CR,VSCR flags 6514 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6515 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6516 6517 /* Restore flags */ 6518 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6519 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6520 6521 dst = (unsigned int*)&vec_out; 6522 6523 printf("%s: %2d => ", name, i); 6524 printf("%08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]); 6525 #if defined TEST_VSCR_SAT 6526 p_vscr = (unsigned int*)𝓋 6527 printf("(%08x, %08x)\n", flags, p_vscr[3]); 6528 #else 6529 printf("(%08x)\n", flags); 6530 #endif 6531 } 6532 } 6533 6534 static void vsldoi_cb (const char* name, test_func_t func_IN, 6535 unused uint32_t test_flags) 6536 { 6537 volatile test_func_t func; 6538 uint32_t* func_buf = get_rwx_area(); 6539 volatile uint32_t flags, tmpcr; 6540 volatile vector unsigned int tmpvscr; 6541 volatile vector unsigned int vec_in1, vec_in2, vec_out, vscr; 6542 unsigned int *src1, *src2, *dst; 6543 int i,j,k; 6544 #if defined TEST_VSCR_SAT 6545 unsigned int* p_vscr; 6546 #endif 6547 6548 for (i=0; i<nb_viargs; i++) { 6549 vec_in1 = (vector unsigned int)viargs[i]; 6550 for (j=0; j<nb_viargs; j++) { 6551 vec_in2 = (vector unsigned int)viargs[j]; 6552 for (k=0; k<16; k+=14) { 6553 vec_out = (vector unsigned int){ 0,0,0,0 }; 6554 6555 /* Patch up the instruction */ 6556 func = init_function( func_IN, func_buf ); 6557 patch_op_imm(&func_buf[0], k, 6, 4); 6558 6559 /* Save flags */ 6560 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6561 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6562 6563 // reset VSCR and CR 6564 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6565 flags = 0; 6566 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6567 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6568 6569 // load inputs -> r14,r15 6570 __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1)); 6571 __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2)); 6572 6573 // do stuff 6574 (*func)(); 6575 6576 // retrieve output <- r17 6577 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 6578 6579 // get CR,VSCR flags 6580 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6581 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6582 6583 /* Restore flags */ 6584 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6585 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6586 6587 src1 = (unsigned int*)&vec_in1; 6588 src2 = (unsigned int*)&vec_in2; 6589 dst = (unsigned int*)&vec_out; 6590 6591 printf("%s: ", name); 6592 printf("%08x%08x%08x%08x, %08x%08x%08x%08x, %u\n", 6593 src1[0], src1[1], src1[2], src1[3], 6594 src2[0], src2[1], src2[2], src2[3], k); 6595 6596 printf("%s: => %08x %08x %08x %08x] ", name, 6597 dst[0], dst[1], dst[2], dst[3]); 6598 #if defined TEST_VSCR_SAT 6599 p_vscr = (unsigned int*)𝓋 6600 printf("(%08x, %08x)\n", flags, p_vscr[3]); 6601 #else 6602 printf("(%08x)\n", flags); 6603 #endif 6604 } 6605 if (verbose) printf("\n"); 6606 } 6607 } 6608 } 6609 6610 /* lvsl, lvsr */ 6611 static void lvs_cb (const char *name, test_func_t func, 6612 unused uint32_t test_flags) 6613 { 6614 volatile uint32_t flags, tmpcr; 6615 volatile vector unsigned int tmpvscr; 6616 volatile vector unsigned int vec_out, vscr; 6617 unsigned int *dst; 6618 int i; 6619 #if defined TEST_VSCR_SAT 6620 unsigned int* p_vscr; 6621 #endif 6622 6623 for (i=-1; i<17; i++) { 6624 vec_out = (vector unsigned int){ 0,0,0,0 }; 6625 6626 // make sure start address is 16 aligned - use viargs[0] 6627 r15 = (HWord_t)&viargs[0]; 6628 r14 = i; 6629 6630 /* Save flags */ 6631 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6632 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6633 6634 // reset VSCR and CR 6635 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6636 flags = 0; 6637 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6638 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6639 6640 // do stuff 6641 (*func)(); 6642 6643 // retrieve output <- r17 6644 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 6645 6646 // get CR,VSCR flags 6647 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6648 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6649 6650 /* Restore flags */ 6651 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6652 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6653 6654 dst = (unsigned int*)&vec_out; 6655 6656 printf("%s %3d, %3d", name, i, 0); 6657 printf(" => %08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]); 6658 printf("(%08x)\n", flags); 6659 } 6660 if (verbose) printf("\n"); 6661 } 6662 6663 static special_t special_av_int_ops[] = { 6664 { 6665 "vsr", /* Two registers arguments */ 6666 &vs128_cb, 6667 }, 6668 { 6669 "vsl", /* Two registers arguments */ 6670 &vs128_cb, 6671 }, 6672 { 6673 "vspltb", /* One reg, one 5-bit uimm arguments */ 6674 &vsplt_cb, 6675 }, 6676 { 6677 "vsplth", /* One reg, one 5-bit uimm arguments */ 6678 &vsplt_cb, 6679 }, 6680 { 6681 "vspltw", /* One reg, one 5-bit uimm arguments */ 6682 &vsplt_cb, 6683 }, 6684 { 6685 "vspltisb", /* One reg, one 5-bit uimm arguments */ 6686 &vspltis_cb, 6687 }, 6688 { 6689 "vspltish", /* One reg, one 5-bit uimm arguments */ 6690 &vspltis_cb, 6691 }, 6692 { 6693 "vspltisw", /* One reg, one 5-bit uimm arguments */ 6694 &vspltis_cb, 6695 }, 6696 { 6697 "vsldoi", /* Two regs, one 4-bit uimm arguments */ 6698 &vsldoi_cb, 6699 }, 6700 { 6701 "lvsl", /* Two regs */ 6702 &lvs_cb, 6703 }, 6704 { 6705 "lvsr", /* Two regs */ 6706 &lvs_cb, 6707 }, 6708 { 6709 NULL, 6710 NULL, 6711 }, 6712 }; 6713 6714 static void test_av_int_special (const char* name, test_func_t func, 6715 uint32_t test_flags) 6716 { 6717 test_special(special_av_int_ops, name, func, test_flags); 6718 } 6719 6720 static void test_av_int_ld_two_regs (const char *name, 6721 test_func_t func, 6722 unused uint32_t test_flags) 6723 { 6724 volatile uint32_t flags, tmpcr; 6725 volatile vector unsigned int tmpvscr; 6726 volatile vector unsigned int vec_in, vec_out, vscr; 6727 unsigned int *src, *dst; 6728 int i,j, k, do_mask; 6729 6730 do_mask = 0; 6731 if (strstr(name, "lvebx") != NULL) do_mask = 1; 6732 if (strstr(name, "lvehx") != NULL) do_mask = 2; 6733 if (strstr(name, "lvewx") != NULL) do_mask = 4; 6734 6735 for (i=0; i<nb_viargs; i++) { 6736 for (j=0; j<16; j+=7) { 6737 vec_out = (vector unsigned int){ 0,0,0,0 }; 6738 6739 // load from viargs array + some dis-alignment 6740 r15 = (HWord_t)&viargs[0]; 6741 r14 = i*16 + j; 6742 6743 /* Save flags */ 6744 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6745 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6746 6747 // reset VSCR and CR 6748 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6749 flags = 0; 6750 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6751 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6752 6753 // do stuff 6754 (*func)(); 6755 6756 // retrieve output <- r17 6757 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 6758 6759 // get CR,VSCR flags 6760 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6761 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6762 6763 /* Restore flags */ 6764 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6765 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6766 6767 vec_in = (vector unsigned int)viargs[i]; 6768 src = (unsigned int*)&vec_in; 6769 dst = (unsigned int*)&vec_out; 6770 6771 /* For lvebx/lvehx/lvewx, as per the documentation, all of 6772 the dest reg except the loaded bits are undefined 6773 afterwards. And different CPUs really do produce 6774 different results. So mask out bits of the result that 6775 are undefined so as to make the test work reliably. */ 6776 if (do_mask == 1) { 6777 char* p = (char*)dst; 6778 for (k = 0; k < 16; k++) 6779 if (k != j) 6780 p[k] = (char)0; 6781 } 6782 if (do_mask == 2) { 6783 short* p = (short*)dst; 6784 for (k = 0; k < 8; k++) 6785 if (k != (j>>1)) 6786 p[k] = (short)0; 6787 } 6788 if (do_mask == 4) { 6789 int* p = (int*)dst; 6790 for (k = 0; k < 4; k++) 6791 if (k != (j>>2)) 6792 p[k] = (int)0; 6793 } 6794 6795 printf("%s %3d, %08x %08x %08x %08x", name, j, src[0], src[1], src[2], src[3]); 6796 printf(" => %08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]); 6797 printf("(%08x)\n", flags); 6798 } 6799 if (verbose) printf("\n"); 6800 } 6801 } 6802 6803 6804 static void test_av_int_st_three_regs (const char *name, 6805 test_func_t func, 6806 unused uint32_t test_flags) 6807 { 6808 volatile uint32_t flags, tmpcr; 6809 volatile vector unsigned int tmpvscr; 6810 volatile vector unsigned int vec_in, vec_out, vscr; 6811 unsigned int *src, *dst; 6812 int i,j; 6813 vector unsigned int* viargs_priv; 6814 6815 // private viargs table to store to 6816 viargs_priv = memalign16(nb_viargs * sizeof(vector unsigned int)); 6817 for (i=0; i<nb_viargs; i++) 6818 viargs_priv[i] = (vector unsigned int) { 0,0,0,0 }; 6819 6820 for (i=0; i<nb_viargs; i++) { 6821 for (j=0; j<16; j+=7) { 6822 // read from viargs 6823 vec_in = (vector unsigned int)viargs[i]; 6824 6825 // store to viargs_priv[0] + some dis-alignment 6826 r16 = (HWord_t)&viargs_priv[0]; 6827 r15 = i*16 + j; 6828 6829 /* Save flags */ 6830 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6831 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6832 6833 // reset VSCR and CR 6834 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6835 flags = 0; 6836 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6837 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6838 6839 // load inputs -> r14 6840 __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in)); 6841 6842 // do stuff 6843 (*func)(); 6844 6845 // Output stored in viargs_priv 6846 6847 // get CR,VSCR flags 6848 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6849 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6850 6851 /* Restore flags */ 6852 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6853 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6854 6855 vec_out = (vector unsigned int)viargs_priv[i]; 6856 src = (unsigned int*)&vec_in; 6857 dst = (unsigned int*)&vec_out; 6858 6859 printf("%s %3d, %08x %08x %08x %08x", name, j, src[0], src[1], src[2], src[3]); 6860 printf(" => %08x %08x %08x %08x ", dst[0], dst[1], dst[2], dst[3]); 6861 printf("(%08x)\n", flags); 6862 } 6863 if (verbose) printf("\n"); 6864 } 6865 } 6866 6867 /* Used in do_tests, indexed by flags->nb_args 6868 Elements correspond to enum test_flags::num args 6869 */ 6870 static test_loop_t altivec_int_loops[] = { 6871 &test_av_int_one_arg, 6872 &test_av_int_two_args, 6873 &test_av_int_three_args, 6874 &test_av_int_two_args, 6875 NULL, 6876 NULL, 6877 &test_av_int_special, 6878 NULL, 6879 &test_av_int_ld_two_regs, 6880 NULL, 6881 test_av_int_st_three_regs, 6882 }; 6883 6884 6885 static void test_av_float_one_arg (const char* name, test_func_t func, 6886 unused uint32_t test_flags) 6887 { 6888 volatile uint32_t flags, tmpcr; 6889 volatile vector unsigned int tmpvscr; 6890 volatile vector float vec_in, vec_out; 6891 volatile vector unsigned int vscr; 6892 unsigned int *src, *dst; 6893 int i; 6894 #if defined TEST_VSCR_SAT 6895 unsigned int* p_vscr; 6896 #endif 6897 6898 /* if we're doing an estimation operation, arrange to zap the 6899 bottom 10-bits of the result as it's basically garbage, and differs 6900 between cpus */ 6901 unsigned int mask 6902 = (strstr(name,"vrsqrtefp") != NULL || 6903 strstr(name, "vrefp") != NULL) 6904 ? 0xFFFFC000 : 0xFFFFFFFF; 6905 6906 for (i=0; i<nb_vfargs; i++) { 6907 vec_in = (vector float)vfargs[i]; 6908 vec_out = (vector float){ 0.0, 0.0, 0.0, 0.0 }; 6909 6910 /* Save flags */ 6911 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6912 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6913 6914 // reset VSCR and CR 6915 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6916 flags = 0; 6917 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6918 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6919 6920 // load input -> r14 6921 __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in)); 6922 6923 // do stuff 6924 (*func)(); 6925 6926 // retrieve output <- r17 6927 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 6928 6929 // get CR,VSCR flags 6930 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6931 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6932 6933 /* Restore flags */ 6934 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6935 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6936 6937 src = (unsigned int*)&vec_in; 6938 dst = (unsigned int*)&vec_out; 6939 6940 printf("%s: %08x %08x %08x %08x\n", name, 6941 src[0], src[1], src[2], src[3]); 6942 printf("%s: => %08x %08x %08x %08x ", name, 6943 dst[0] & mask, dst[1] & mask, dst[2] & mask, dst[3] & mask); 6944 #if defined TEST_VSCR_SAT 6945 p_vscr = (unsigned int*)𝓋 6946 printf("(%08x, %08x)\n", flags, p_vscr[3]); 6947 #else 6948 printf("(%08x)\n", flags); 6949 #endif 6950 } 6951 } 6952 6953 static void test_av_float_two_args (const char* name, test_func_t func, 6954 unused uint32_t test_flags) 6955 { 6956 volatile uint32_t flags, tmpcr; 6957 volatile vector unsigned int tmpvscr; 6958 volatile vector float vec_in1, vec_in2, vec_out; 6959 volatile vector unsigned int vscr; 6960 unsigned int *src1, *src2, *dst; 6961 int i,j; 6962 #if defined TEST_VSCR_SAT 6963 unsigned int* p_vscr; 6964 #endif 6965 6966 for (i=0; i<nb_vfargs; i++) { 6967 for (j=0; j<nb_vfargs; j+=3) { 6968 vec_in1 = (vector float)vfargs[i]; 6969 vec_in2 = (vector float)vfargs[j]; 6970 vec_out = (vector float){ 0.0, 0.0, 0.0, 0.0 }; 6971 6972 /* Save flags */ 6973 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 6974 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 6975 6976 // reset VSCR and CR 6977 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 6978 flags = 0; 6979 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 6980 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 6981 6982 // load inputs -> r14,r15 6983 __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1)); 6984 __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2)); 6985 6986 // do stuff 6987 (*func)(); 6988 6989 // retrieve output <- r17 6990 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 6991 6992 // get CR,VSCR flags 6993 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 6994 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 6995 6996 /* Restore flags */ 6997 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 6998 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 6999 7000 src1 = (unsigned int*)&vec_in1; 7001 src2 = (unsigned int*)&vec_in2; 7002 dst = (unsigned int*)&vec_out; 7003 7004 printf("%s: %08x%08x%08x%08x, %08x%08x%08x%08x\n", name, 7005 src1[0], src1[1], src1[2], src1[3], 7006 src2[0], src2[1], src2[2], src2[3]); 7007 printf("%s: => %08x %08x %08x %08x ", name, 7008 dst[0], dst[1], dst[2], dst[3]); 7009 #if defined TEST_VSCR_SAT 7010 p_vscr = (unsigned int*)𝓋 7011 printf("(%08x, %08x)\n", flags, p_vscr[3]); 7012 #else 7013 printf("(%08x)\n", flags); 7014 #endif 7015 } 7016 if (verbose) printf("\n"); 7017 } 7018 } 7019 7020 static void test_av_float_three_args (const char* name, test_func_t func, 7021 unused uint32_t test_flags) 7022 { 7023 volatile uint32_t flags, tmpcr; 7024 volatile vector unsigned int tmpvscr; 7025 volatile vector float vec_in1, vec_in2, vec_in3, vec_out; 7026 volatile vector unsigned int vscr; 7027 unsigned int *src1, *src2, *src3, *dst; 7028 int i,j,k,n; 7029 #if defined TEST_VSCR_SAT 7030 unsigned int* p_vscr; 7031 #endif 7032 7033 for (i=0; i<nb_vfargs; i++) { 7034 for (j=0; j<nb_vfargs; j+=3) { 7035 for (k=0; k<nb_vfargs; k+=5) { 7036 vec_in1 = (vector float)vfargs[i]; 7037 vec_in2 = (vector float)vfargs[j]; 7038 vec_in3 = (vector float)vfargs[k]; 7039 vec_out = (vector float){ 0.0, 0.0, 0.0, 0.0 }; 7040 7041 /* Save flags */ 7042 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 7043 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 7044 7045 // reset VSCR and CR 7046 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 7047 flags = 0; 7048 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 7049 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 7050 7051 // load inputs -> r14,r15,r16 7052 __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in1)); 7053 __asm__ __volatile__ ("vor 15,%0,%0" : : "v" (vec_in2)); 7054 __asm__ __volatile__ ("vor 16,%0,%0" : : "v" (vec_in3)); 7055 7056 // do stuff 7057 (*func)(); 7058 7059 // retrieve output <- r17 7060 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 7061 7062 // get CR,VSCR flags 7063 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 7064 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 7065 7066 /* Restore flags */ 7067 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 7068 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 7069 7070 src1 = (unsigned int*)&vec_in1; 7071 src2 = (unsigned int*)&vec_in2; 7072 src3 = (unsigned int*)&vec_in3; 7073 dst = (unsigned int*)&vec_out; 7074 7075 /* Valgrind emulation for vmaddfp and vnmsubfp generates negative 7076 * NAN. Technically, NAN is not positive or negative so mask off 7077 * the sign bit to eliminate false errors. 7078 * 7079 * Valgrind emulation is creating negative zero. Mask off negative 7080 * from zero result. 7081 * 7082 * These are only an issue as we are printing the result in hex. 7083 * 7084 * The VEX emulation accuracy for the vmaddfp and vnmsubfp 7085 * instructions is off by a single bit in the least significant 7086 * bit position of the result. Mask off the LSB. 7087 */ 7088 7089 for (n=0; n<4; n++) { 7090 /* NAN result*/ 7091 if (((dst[n] & 0x7F800000) == 0x7F800000) && 7092 ((dst[n] & 0x7FFFFF) != 0)) 7093 dst[n] &= 0x7FFFFFFF; 7094 7095 /* Negative zero result */ 7096 else if (dst[n] == 0x80000000) 7097 dst[n] = 0x0; 7098 7099 else 7100 /* The actual result and the emulated result for the 7101 * vmaddfp and vnmsubfp instructions sometimes differ 7102 * in the least significant bit. Mask off the bit. 7103 */ 7104 dst[n] &= 0xFFFFFFFE; 7105 } 7106 7107 printf("%s: %08x%08x%08x%08x, %08x%08x%08x%08x, %08x%08x%08x%08x\n", name, 7108 src1[0], src1[1], src1[2], src1[3], 7109 src2[0], src2[1], src2[2], src2[3], 7110 src3[0], src3[1], src3[2], src3[3]); 7111 printf("%s: => %08x %08x %08x %08x ", name, 7112 dst[0], dst[1], dst[2], dst[3]); 7113 #if defined TEST_VSCR_SAT 7114 p_vscr = (unsigned int*)𝓋 7115 printf("(%08x, %08x)\n", flags, p_vscr[3]); 7116 #else 7117 printf("(%08x)\n", flags); 7118 #endif 7119 } 7120 if (verbose) printf("\n"); 7121 } 7122 } 7123 } 7124 7125 static void vcvt_cb (const char* name, test_func_t func_IN, 7126 unused uint32_t test_flags) 7127 { 7128 volatile test_func_t func; 7129 uint32_t* func_buf = get_rwx_area(); 7130 volatile uint32_t flags, tmpcr; 7131 volatile vector unsigned int tmpvscr; 7132 volatile vector unsigned int vec_in, vec_out, vscr; 7133 unsigned int *src, *dst; 7134 int i,j; 7135 #if defined TEST_VSCR_SAT 7136 unsigned int* p_vscr; 7137 #endif 7138 7139 for (i=0; i<nb_vfargs; i++) { 7140 vec_in = (vector unsigned int)vfargs[i]; 7141 7142 for (j=0; j<32; j+=9) { 7143 vec_out = (vector unsigned int){ 0,0,0,0 }; 7144 7145 /* Patch up the instruction */ 7146 func = init_function( func_IN, func_buf ); 7147 patch_op_imm(&func_buf[0], j, 16, 5); 7148 7149 /* Save flags */ 7150 __asm__ __volatile__ ("mfcr %0" : "=r" (tmpcr)); 7151 __asm__ __volatile__ ("mfvscr %0" : "=vr" (tmpvscr)); 7152 7153 // reset VSCR and CR 7154 vscr = (vector unsigned int){ 0,0,0,DEFAULT_VSCR }; 7155 flags = 0; 7156 __asm__ __volatile__ ("mtvscr %0" : : "v" (vscr) ); 7157 __asm__ __volatile__ ("mtcr %0" : : "r" (flags)); 7158 7159 // load input -> r14 7160 __asm__ __volatile__ ("vor 14,%0,%0" : : "v" (vec_in)); 7161 7162 // do stuff 7163 (*func)(); 7164 7165 // retrieve output <- r17 7166 __asm__ __volatile__ ("vor %0,17,17" : "=vr" (vec_out)); 7167 7168 // get CR,VSCR flags 7169 __asm__ __volatile__ ("mfcr %0" : "=r" (flags)); 7170 __asm__ __volatile__ ("mfvscr %0" : "=vr" (vscr)); 7171 7172 /* Restore flags */ 7173 __asm__ __volatile__ ("mtcr %0" : : "r" (tmpcr)); 7174 __asm__ __volatile__ ("mtvscr %0" : : "v" (tmpvscr)); 7175 7176 src = (unsigned int*)&vec_in; 7177 dst = (unsigned int*)&vec_out; 7178 7179 printf("%s: %08x (%13e), %2u", name, src[0], *(float*)(&src[0]), j); 7180 printf(" => %08x (%13e) ", dst[0], *(float*)(&dst[0])); 7181 // printf(" => %08x ", dst[0]); 7182 #if defined TEST_VSCR_SAT 7183 p_vscr = (unsigned int*)𝓋 7184 printf("(%08x, %08x)\n", flags, p_vscr[3]); 7185 #else 7186 printf("(%08x)\n", flags); 7187 #endif 7188 } 7189 if (verbose) printf("\n"); 7190 } 7191 } 7192 7193 static special_t special_av_float_ops[] = { 7194 { 7195 "vcfux", /* One reg, one 5-bit uimm argument */ 7196 &vcvt_cb, 7197 }, 7198 { 7199 "vcfsx", /* One reg, one 5-bit uimm argument */ 7200 &vcvt_cb, 7201 }, 7202 { 7203 "vctuxs", /* One reg, one 5-bit uimm argument */ 7204 &vcvt_cb, 7205 }, 7206 { 7207 "vcfux", /* One reg, one 5-bit uimm argument */ 7208 &vcvt_cb, 7209 }, 7210 { 7211 "vctsxs", /* One reg, one 5-bit uimm argument */ 7212 &vcvt_cb, 7213 }, 7214 { 7215 NULL, 7216 NULL, 7217 }, 7218 }; 7219 7220 static void test_av_float_special (const char* name, test_func_t func, 7221 uint32_t test_flags) 7222 { 7223 test_special(special_av_float_ops, name, func, test_flags); 7224 } 7225 7226 /* Used in do_tests, indexed by flags->nb_args 7227 Elements correspond to enum test_flags::num args 7228 */ 7229 static test_loop_t altivec_float_loops[] = { 7230 &test_av_float_one_arg, 7231 &test_av_float_two_args, 7232 &test_av_float_three_args, 7233 &test_av_float_two_args, 7234 NULL, 7235 NULL, 7236 &test_av_float_special, 7237 NULL, 7238 NULL, 7239 NULL, 7240 NULL, 7241 }; 7242 7243 #endif /* defined (HAS_ALTIVEC) */ 7244 7245 7246 #if defined (IS_PPC405) 7247 static void test_ppc405 (const char* name, test_func_t func, 7248 unused uint32_t test_flags) 7249 { 7250 volatile uint32_t res, flags, xer, tmpcr, tmpxer; 7251 int i, j, k; 7252 7253 for (i=0; i<nb_iargs; i++) { 7254 for (j=0; j<nb_iargs; j++) { 7255 for (k=0; k<nb_iargs; k++) { 7256 r14 = iargs[i]; 7257 r15 = iargs[j]; 7258 /* Beware: the third argument and the result 7259 * are in the same register 7260 */ 7261 r17 = iargs[k]; 7262 7263 /* Save flags */ 7264 __asm__ __volatile__ ("mfcr 18"); 7265 tmpcr = r18; 7266 __asm__ __volatile__ ("mfxer 18"); 7267 tmpxer = r18; 7268 7269 /* Set up flags for test */ 7270 r18 = 0; 7271 __asm__ __volatile__ ("mtcr 18"); 7272 __asm__ __volatile__ ("mtxer 18"); 7273 (*func)(); 7274 __asm__ __volatile__ ("mfcr 18"); 7275 flags = r18; 7276 __asm__ __volatile__ ("mfxer 18"); 7277 xer = r18; 7278 res = r17; 7279 7280 /* Restore flags */ 7281 r18 = tmpcr; 7282 __asm__ __volatile__ ("mtcr 18"); 7283 r18 = tmpxer; 7284 __asm__ __volatile__ ("mtxer 18"); 7285 7286 printf("%s %08x, %08x, %08x => %08x (%08x %08x)\n", 7287 name, iargs[i], iargs[j], iargs[k], res, flags, xer); 7288 } 7289 if (verbose) printf("\n"); 7290 } 7291 } 7292 } 7293 #endif /* defined (IS_PPC405) */ 7294 7295 static int check_filter (char *filter) 7296 { 7297 char *c; 7298 int ret = 1; 7299 7300 if (filter != NULL) { 7301 c = strchr(filter, '*'); 7302 if (c != NULL) { 7303 *c = '\0'; 7304 ret = 0; 7305 } 7306 } 7307 7308 return ret; 7309 } 7310 7311 static int check_name (const char* name, const char *filter, 7312 int exact) 7313 { 7314 int nlen, flen; 7315 int ret = 0; 7316 7317 if (filter != NULL) { 7318 for (; isspace(*name); name++) 7319 continue; 7320 FDPRINTF("Check '%s' againt '%s' (%s match)\n", 7321 name, filter, exact ? "exact" : "starting"); 7322 nlen = strlen(name); 7323 flen = strlen(filter); 7324 if (exact) { 7325 if (nlen == flen && memcmp(name, filter, flen) == 0) 7326 ret = 1; 7327 } else { 7328 if (flen <= nlen && memcmp(name, filter, flen) == 0) 7329 ret = 1; 7330 } 7331 } else { 7332 ret = 1; 7333 } 7334 return ret; 7335 } 7336 7337 7338 7339 typedef struct insn_sel_flags_t_struct { 7340 int one_arg, two_args, three_args; 7341 int arith, logical, compare, ldst; 7342 int integer, floats, p405, altivec, faltivec; 7343 int cr; 7344 } insn_sel_flags_t; 7345 7346 static void do_tests ( insn_sel_flags_t seln_flags, 7347 char *filter) 7348 { 7349 #if defined (IS_PPC405) 7350 test_loop_t tmpl; 7351 #endif 7352 test_loop_t *loop; 7353 test_t *tests; 7354 int nb_args, type, family; 7355 int i, j, n; 7356 int exact; 7357 7358 exact = check_filter(filter); 7359 n = 0; 7360 for (i=0; all_tests[i].name != NULL; i++) { 7361 nb_args = all_tests[i].flags & PPC_NB_ARGS; 7362 /* Check number of arguments */ 7363 if ((nb_args == 1 && !seln_flags.one_arg) || 7364 (nb_args == 2 && !seln_flags.two_args) || 7365 (nb_args == 3 && !seln_flags.three_args)) 7366 continue; 7367 /* Check instruction type */ 7368 type = all_tests[i].flags & PPC_TYPE; 7369 if ((type == PPC_ARITH && !seln_flags.arith) || 7370 (type == PPC_LOGICAL && !seln_flags.logical) || 7371 (type == PPC_COMPARE && !seln_flags.compare) || 7372 (type == PPC_LDST && !seln_flags.ldst) || 7373 (type == PPC_POPCNT && !seln_flags.arith)) 7374 continue; 7375 /* Check instruction family */ 7376 family = all_tests[i].flags & PPC_FAMILY; 7377 if ((family == PPC_INTEGER && !seln_flags.integer) || 7378 (family == PPC_FLOAT && !seln_flags.floats) || 7379 (family == PPC_405 && !seln_flags.p405) || 7380 (family == PPC_ALTIVEC && !seln_flags.altivec) || 7381 (family == PPC_FALTIVEC && !seln_flags.faltivec)) 7382 continue; 7383 /* Check flags update */ 7384 if (((all_tests[i].flags & PPC_CR) && seln_flags.cr == 0) || 7385 (!(all_tests[i].flags & PPC_CR) && seln_flags.cr == 1)) 7386 continue; 7387 /* All passed, do the tests */ 7388 tests = all_tests[i].tests; 7389 /* Select the test loop */ 7390 switch (family) { 7391 case PPC_INTEGER: 7392 loop = &int_loops[nb_args - 1]; 7393 break; 7394 case PPC_FLOAT: 7395 #if !defined (NO_FLOAT) 7396 loop = &float_loops[nb_args - 1]; 7397 break; 7398 #else 7399 fprintf(stderr, "Sorry. " 7400 "PPC floating point instructions tests " 7401 "are disabled on your host\n"); 7402 #endif /* !defined (NO_FLOAT) */ 7403 7404 case PPC_405: 7405 #if defined (IS_PPC405) 7406 tmpl = &test_ppc405; 7407 loop = &tmpl; 7408 break; 7409 #else 7410 fprintf(stderr, "Sorry. " 7411 "PPC405 instructions tests are disabled on your host\n"); 7412 continue; 7413 #endif /* defined (IS_PPC405) */ 7414 case PPC_ALTIVEC: 7415 #if defined (HAS_ALTIVEC) 7416 loop = &altivec_int_loops[nb_args - 1]; 7417 break; 7418 #else 7419 fprintf(stderr, "Sorry. " 7420 "Altivec instructions tests are disabled on your host\n"); 7421 continue; 7422 #endif 7423 case PPC_FALTIVEC: 7424 #if defined (HAS_ALTIVEC) 7425 loop = &altivec_float_loops[nb_args - 1]; 7426 break; 7427 #else 7428 fprintf(stderr, "Sorry. " 7429 "Altivec float instructions tests " 7430 "are disabled on your host\n"); 7431 #endif 7432 continue; 7433 default: 7434 printf("ERROR: unknown insn family %08x\n", family); 7435 continue; 7436 } 7437 if (1 || verbose > 0) 7438 printf("%s:\n", all_tests[i].name); 7439 for (j=0; tests[j].name != NULL; j++) { 7440 if (check_name(tests[j].name, filter, exact)) { 7441 if (verbose > 1) 7442 printf("Test instruction %s\n", tests[j].name); 7443 (*loop)(tests[j].name, tests[j].func, all_tests[i].flags); 7444 printf("\n"); 7445 n++; 7446 } 7447 } 7448 if (verbose) printf("\n"); 7449 } 7450 printf("All done. Tested %d different instructions\n", n); 7451 } 7452 7453 7454 static void usage (void) 7455 { 7456 #if !defined (USAGE_SIMPLE) 7457 fprintf(stderr, 7458 "jm-insns [-1] [-2] [-3] [-*] [-t <type>] [-f <family>] [-u] " 7459 "[-n <filter>] [-r <test_rigour>] [-h]\n" 7460 "\t-1: test opcodes with one argument\n" 7461 "\t-2: test opcodes with two arguments\n" 7462 "\t-3: test opcodes with three arguments\n" 7463 "\t-*: launch test without checking the number of arguments\n" 7464 "\t-t: launch test for instructions of type <type>\n" 7465 "\t recognized types:\n" 7466 "\t\tarith (or a)\n" 7467 "\t\tlogical (or l)\n" 7468 "\t\tcompare (or c)\n" 7469 "\t\tstoreload (or s)\n" 7470 "\t-f: launch test for instructions of family <family>\n" 7471 "\t recognized families:\n" 7472 "\t\tinteger (or i)\n" 7473 "\t\tfloat (or f)\n" 7474 "\t\tppc405 (or mac)\n" 7475 "\t\taltivec (or a)\n" 7476 "\t-u: test instructions that update flags\n" 7477 "\t-n: filter instructions with <filter>\n" 7478 "\t <filter> can be in two forms:\n" 7479 "\t\tname : filter functions that exactly match <name>\n" 7480 "\t\tname* : filter functions that start with <name>\n" 7481 "\t-r: set size of arg tables to use to define <test_rigour>\n" 7482 "\t recognized types:\n" 7483 "\t\tlarge (or l)\n" 7484 "\t\tsmall (or s) - default\n" 7485 "\t-v: verbose (-v -v for more)\n" 7486 "\t-h: print this help\n" 7487 ); 7488 #else // #if !defined (USAGE_SIMPLE) 7489 fprintf(stderr, 7490 "Usage: jm-insns [OPTION]\n" 7491 "\t-i: test integer instructions (default)\n" 7492 "\t-f: test floating point instructions\n" 7493 "\t-a: test altivec instructions\n" 7494 "\t-A: test all (int, fp, altivec) instructions\n" 7495 "\t-v: be verbose\n" 7496 "\t-h: display this help and exit\n" 7497 ); 7498 #endif // #if !defined (USAGE_SIMPLE) 7499 } 7500 7501 7502 7503 int main (int argc, char **argv) 7504 { 7505 #if !defined (USAGE_SIMPLE) 7506 //////////////////////////////////////////////////////////////////////// 7507 unsigned char *tmp, *filter = NULL; 7508 insn_sel_flags_t flags; 7509 int c; 7510 7511 // check HWord_t really is a host word 7512 assert(sizeof(void*) == sizeof(HWord_t)); 7513 7514 flags.one_arg = 0; 7515 flags.two_args = 0; 7516 flags.three_args = 0; 7517 flags.arith = 0; 7518 flags.logical = 0; 7519 flags.compare = 0; 7520 flags.ldst = 0; 7521 flags.integer = 0; 7522 flags.floats = 0; 7523 flags.p405 = 0; 7524 flags.altivec = 0; 7525 flags.faltivec = 0; 7526 flags.cr = -1; 7527 7528 while ((c = getopt(argc, argv, "123t:f:n:r:uvh")) != -1) { 7529 switch (c) { 7530 case '1': 7531 flags.one_arg = 1; 7532 break; 7533 case '2': 7534 flags.two_args = 1; 7535 break; 7536 case '3': 7537 flags.three_args = 1; 7538 break; 7539 case 't': 7540 tmp = optarg; 7541 if (strcmp(tmp, "arith") == 0 || strcmp(tmp, "a") == 0) { 7542 flags.arith = 1; 7543 } else if (strcmp(tmp, "logical") == 0 || strcmp(tmp, "l") == 0) { 7544 flags.logical = 1; 7545 } else if (strcmp(tmp, "compare") == 0 || strcmp(tmp, "c") == 0) { 7546 flags.compare = 1; 7547 } else if (strcmp(tmp, "storeload") == 0 || strcmp(tmp, "s") == 0) { 7548 flags.ldst = 1; 7549 } else { 7550 goto bad_arg; 7551 } 7552 break; 7553 case 'f': 7554 tmp = optarg; 7555 if (strcmp(tmp, "integer") == 0 || strcmp(tmp, "i") == 0) { 7556 flags.integer = 1; 7557 } else if (strcmp(tmp, "float") == 0 || strcmp(tmp, "f") == 0) { 7558 flags.floats = 1; 7559 } else if (strcmp(tmp, "ppc405") == 0 || strcmp(tmp, "mac") == 0) { 7560 flags.p405 = 1; 7561 } else if (strcmp(tmp, "altivec") == 0 || strcmp(tmp, "a") == 0) { 7562 flags.altivec = 1; 7563 flags.faltivec = 1; 7564 } else { 7565 goto bad_arg; 7566 } 7567 break; 7568 case 'n': 7569 filter = optarg; 7570 break; 7571 case 'r': 7572 tmp = optarg; 7573 if (strcmp(tmp, "large") == 0 || strcmp(tmp, "l") == 0) { 7574 arg_list_size = 1; 7575 } else if (strcmp(tmp, "small") == 0 || strcmp(tmp, "s") == 0) { 7576 arg_list_size = 0; 7577 } else { 7578 goto bad_arg; 7579 } 7580 break; 7581 7582 case 'u': 7583 flags.cr = 1; 7584 break; 7585 case 'h': 7586 usage(); 7587 return 0; 7588 case 'v': 7589 verbose++; 7590 break; 7591 default: 7592 usage(); 7593 fprintf(stderr, "Unknown argument: '%c'\n", c); 7594 return 1; 7595 bad_arg: 7596 usage(); 7597 fprintf(stderr, "Bad argument for '%c': '%s'\n", c, tmp); 7598 return 1; 7599 } 7600 } 7601 if (argc != optind) { 7602 usage(); 7603 fprintf(stderr, "Bad number of arguments\n"); 7604 return 1; 7605 } 7606 7607 // Default n_args 7608 if (flags.one_arg == 0 && flags.two_args == 0 && flags.three_args == 0) { 7609 flags.one_arg = 1; 7610 flags.two_args = 1; 7611 flags.three_args = 1; 7612 } 7613 // Default type 7614 if (flags.arith == 0 && flags.logical == 0 && 7615 flags.compare == 0 && flags.ldst == 0) { 7616 flags.arith = 1; 7617 flags.logical = 1; 7618 flags.compare = 1; 7619 flags.ldst = 1; 7620 } 7621 // Default family 7622 if (flags.integer == 0 && flags.floats == 0 && 7623 flags.p405 == 0 && flags.altivec == 0 && flags.faltivec == 0) { 7624 flags.integer = 1; 7625 flags.floats = 1; 7626 flags.p405 = 1; 7627 flags.altivec = 1; 7628 flags.faltivec = 1; 7629 } 7630 // Default cr update 7631 if (flags.cr == -1) 7632 flags.cr = 2; // both 7633 7634 #else // #if !defined (USAGE_SIMPLE) 7635 //////////////////////////////////////////////////////////////////////// 7636 /* Simple usage: 7637 ./jm-insns -i => int insns 7638 ./jm-insns -f => fp insns 7639 ./jm-insns -a => av insns 7640 ./jm-insns -A => int, fp and avinsns 7641 */ 7642 char *filter = NULL; 7643 insn_sel_flags_t flags; 7644 int c; 7645 7646 // Args 7647 flags.one_arg = 1; 7648 flags.two_args = 1; 7649 flags.three_args = 1; 7650 // Type 7651 flags.arith = 1; 7652 flags.logical = 1; 7653 flags.compare = 1; 7654 flags.ldst = 1; 7655 // Family 7656 flags.integer = 0; 7657 flags.floats = 0; 7658 flags.p405 = 0; 7659 flags.altivec = 0; 7660 flags.faltivec = 0; 7661 // Flags 7662 flags.cr = 2; 7663 7664 while ((c = getopt(argc, argv, "ifahvA")) != -1) { 7665 switch (c) { 7666 case 'i': 7667 flags.integer = 1; 7668 break; 7669 case 'f': 7670 flags.floats = 1; 7671 break; 7672 case 'a': 7673 flags.altivec = 1; 7674 flags.faltivec = 1; 7675 break; 7676 case 'A': 7677 flags.integer = 1; 7678 flags.floats = 1; 7679 flags.altivec = 1; 7680 flags.faltivec = 1; 7681 break; 7682 case 'h': 7683 usage(); 7684 return 0; 7685 case 'v': 7686 verbose++; 7687 break; 7688 default: 7689 usage(); 7690 fprintf(stderr, "Unknown argument: '%c'\n", c); 7691 return 1; 7692 } 7693 } 7694 7695 arg_list_size = 0; 7696 #endif // #if !defined (USAGE_SIMPLE) 7697 7698 7699 build_iargs_table(); 7700 build_fargs_table(); 7701 build_ii16_table(); 7702 #if defined (HAS_ALTIVEC) 7703 if (flags.altivec || flags.faltivec) { 7704 build_viargs_table(); 7705 build_vfargs_table(); 7706 } 7707 #endif 7708 // dump_iargs(); 7709 // dump_iargs16(); 7710 // dump_vfargs(); 7711 7712 if (verbose > 1) { 7713 printf("\nInstruction Selection:\n"); 7714 printf(" n_args: \n"); 7715 printf(" one_arg = %d\n", flags.one_arg); 7716 printf(" two_args = %d\n", flags.two_args); 7717 printf(" three_args = %d\n", flags.three_args); 7718 printf(" type: \n"); 7719 printf(" arith = %d\n", flags.arith); 7720 printf(" logical = %d\n", flags.logical); 7721 printf(" compare = %d\n", flags.compare); 7722 printf(" ldst = %d\n", flags.ldst); 7723 printf(" family: \n"); 7724 printf(" integer = %d\n", flags.integer); 7725 printf(" floats = %d\n", flags.floats); 7726 printf(" p405 = %d\n", flags.p405); 7727 printf(" altivec = %d\n", flags.altivec); 7728 printf(" faltivec = %d\n", flags.faltivec); 7729 printf(" cr update: \n"); 7730 printf(" cr = %d\n", flags.cr); 7731 printf("\n"); 7732 printf(" num args: \n"); 7733 printf(" iargs - %d\n", nb_iargs); 7734 printf(" fargs - %d\n", nb_fargs); 7735 #if defined (HAS_ALTIVEC) 7736 printf(" viargs - %d\n", nb_viargs); 7737 printf(" vfargs - %d\n", nb_vfargs); 7738 #endif 7739 printf("\n"); 7740 } 7741 7742 do_tests( flags, filter ); 7743 7744 return 0; 7745 } 7746