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