1/* 2 * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, see <http://www.gnu.org/licenses/>. 16 */ 17 18DEF_MACRO( 19 LIKELY, /* NAME */ 20 __builtin_expect((X),1), /* BEH */ 21 () /* attribs */ 22) 23 24DEF_MACRO( 25 UNLIKELY, /* NAME */ 26 __builtin_expect((X),0), /* BEH */ 27 () /* attribs */ 28) 29 30DEF_MACRO( 31 CANCEL, /* macro name */ 32 {if (thread->last_pkt) thread->last_pkt->slot_cancelled |= (1<<insn->slot); return;} , /* behavior */ 33 (A_CONDEXEC) 34) 35 36DEF_MACRO( 37 LOAD_CANCEL, /* macro name */ 38 {mem_general_load_cancelled(thread,EA,insn);CANCEL;} , /* behavior */ 39 (A_CONDEXEC) 40) 41 42DEF_MACRO( 43 STORE_CANCEL, /* macro name */ 44 {mem_general_store_cancelled(thread,EA,insn);CANCEL;} , /* behavior */ 45 (A_CONDEXEC) 46) 47 48DEF_MACRO( 49 fMAX, /* macro name */ 50 (((A) > (B)) ? (A) : (B)), /* behavior */ 51 /* optional attributes */ 52) 53 54DEF_MACRO( 55 fMIN, /* macro name */ 56 (((A) < (B)) ? (A) : (B)), /* behavior */ 57 /* optional attributes */ 58) 59 60DEF_MACRO( 61 fABS, /* macro name */ 62 (((A)<0)?(-(A)):(A)), /* behavior */ 63 /* optional attributes */ 64) 65 66 67/* Bit insert */ 68DEF_MACRO( 69 fINSERT_BITS, 70 { 71 REG = ((REG) & ~(((fCONSTLL(1)<<(WIDTH))-1)<<(OFFSET))) | (((INVAL) & ((fCONSTLL(1)<<(WIDTH))-1)) << (OFFSET)); 72 }, 73 /* attribs */ 74) 75 76/* Bit extract */ 77DEF_MACRO( 78 fEXTRACTU_BITS, 79 (fZXTN(WIDTH,32,(INREG >> OFFSET))), 80 /* attribs */ 81) 82 83DEF_MACRO( 84 fEXTRACTU_BIDIR, 85 (fZXTN(WIDTH,32,fBIDIR_LSHIFTR((INREG),(OFFSET),4_8))), 86 /* attribs */ 87) 88 89DEF_MACRO( 90 fEXTRACTU_RANGE, 91 (fZXTN((HIBIT-LOWBIT+1),32,(INREG >> LOWBIT))), 92 /* attribs */ 93) 94 95DEF_MACRO( 96 f8BITSOF, 97 ( (VAL) ? 0xff : 0x00), 98 /* attribs */ 99) 100 101DEF_MACRO( 102 fLSBOLD, 103 ((VAL) & 1), 104 () 105) 106 107DEF_MACRO( 108 fLSBNEW, 109 predlog_read(thread,PNUM), 110 () 111) 112 113DEF_MACRO( 114 fLSBNEW0, 115 predlog_read(thread,0), 116 () 117) 118 119DEF_MACRO( 120 fLSBNEW1, 121 predlog_read(thread,1), 122 () 123) 124 125DEF_MACRO( 126 fLSBOLDNOT, 127 (!fLSBOLD(VAL)), 128 () 129) 130 131DEF_MACRO( 132 fLSBNEWNOT, 133 (!fLSBNEW(PNUM)), 134 () 135) 136 137DEF_MACRO( 138 fLSBNEW0NOT, 139 (!fLSBNEW0), 140 () 141) 142 143DEF_MACRO( 144 fLSBNEW1NOT, 145 (!fLSBNEW1), 146 () 147) 148 149DEF_MACRO( 150 fNEWREG, 151 ({if (newvalue_missing(thread,RNUM) || 152 IS_CANCELLED(insn->new_value_producer_slot)) CANCEL; reglog_read(thread,RNUM);}), 153 (A_DOTNEWVALUE,A_RESTRICT_SLOT0ONLY) 154) 155// Store new with a missing newvalue or cancelled goes out as a zero byte store in V65 156// take advantage of the fact that reglog_read returns zero for not valid rnum 157DEF_MACRO( 158 fNEWREG_ST, 159 ({if (newvalue_missing(thread,RNUM) || 160 IS_CANCELLED(insn->new_value_producer_slot)) { STORE_ZERO; RNUM = -1; }; reglog_read(thread,RNUM);}), 161 (A_DOTNEWVALUE,A_RESTRICT_SLOT0ONLY) 162) 163 164DEF_MACRO( 165 fSATUVALN, 166 ({fSET_OVERFLOW(); ((VAL) < 0) ? 0 : ((1LL<<(N))-1);}), 167 () 168) 169 170DEF_MACRO( 171 fSATVALN, 172 ({fSET_OVERFLOW(); ((VAL) < 0) ? (-(1LL<<((N)-1))) : ((1LL<<((N)-1))-1);}), 173 () 174) 175 176DEF_MACRO( 177 fZXTN, /* macro name */ 178 ((VAL) & ((1LL<<(N))-1)), 179 /* attribs */ 180) 181 182DEF_MACRO( 183 fSXTN, /* macro name */ 184 ((fZXTN(N,M,VAL) ^ (1LL<<((N)-1))) - (1LL<<((N)-1))), 185 /* attribs */ 186) 187 188DEF_MACRO( 189 fSATN, 190 ((fSXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATVALN(N,VAL)), 191 () 192) 193 194DEF_MACRO( 195 fADDSAT64, 196 { 197 size8u_t __a = fCAST8u(A); 198 size8u_t __b = fCAST8u(B); 199 size8u_t __sum = __a + __b; 200 size8u_t __xor = __a ^ __b; 201 const size8u_t __mask = 0x8000000000000000ULL; 202 if (__xor & __mask) { 203 /* Opposite signs, OK */ 204 DST = __sum; 205 } else if ((__a ^ __sum) & __mask) { 206 /* Signs mismatch */ 207 if (__sum & __mask) { 208 /* overflowed to negative, make max pos */ 209 DST=0x7FFFFFFFFFFFFFFFLL; fSET_OVERFLOW(); 210 } else { 211 /* overflowed to positive, make max neg */ 212 DST=0x8000000000000000LL; fSET_OVERFLOW(); 213 } 214 } else { 215 /* signs did not mismatch, OK */ 216 DST = __sum; 217 } 218 }, 219 () 220) 221 222DEF_MACRO( 223 fSATUN, 224 ((fZXTN(N,64,VAL) == (VAL)) ? (VAL) : fSATUVALN(N,VAL)), 225 () 226) 227 228DEF_MACRO( 229 fSATH, 230 (fSATN(16,VAL)), 231 () 232) 233 234 235DEF_MACRO( 236 fSATUH, 237 (fSATUN(16,VAL)), 238 () 239) 240 241DEF_MACRO( 242 fSATUB, 243 (fSATUN(8,VAL)), 244 () 245) 246DEF_MACRO( 247 fSATB, 248 (fSATN(8,VAL)), 249 () 250) 251 252 253/*************************************/ 254/* immediate extension */ 255/*************************************/ 256 257DEF_MACRO( 258 fIMMEXT, 259 (IMM = IMM), 260 (A_EXTENDABLE) 261) 262 263DEF_MACRO( 264 fMUST_IMMEXT, 265 fIMMEXT(IMM), 266 (A_EXTENDABLE) 267) 268 269DEF_MACRO( 270 fPCALIGN, 271 IMM=(IMM & ~PCALIGN_MASK), 272 (A_EXTENDABLE) 273) 274 275/*************************************/ 276/* Read and Write Implicit Regs */ 277/*************************************/ 278 279DEF_MACRO( 280 fREAD_LR, /* read link register */ 281 (READ_RREG(REG_LR)), /* behavior */ 282 () 283) 284 285DEF_MACRO( 286 fWRITE_LR, /* write lr */ 287 WRITE_RREG(REG_LR,A), /* behavior */ 288 (A_IMPLICIT_WRITES_LR) 289) 290 291DEF_MACRO( 292 fWRITE_FP, /* write sp */ 293 WRITE_RREG(REG_FP,A), /* behavior */ 294 (A_IMPLICIT_WRITES_FP) 295) 296 297DEF_MACRO( 298 fWRITE_SP, /* write sp */ 299 WRITE_RREG(REG_SP,A), /* behavior */ 300 (A_IMPLICIT_WRITES_SP) 301) 302 303DEF_MACRO( 304 fREAD_SP, /* read stack pointer */ 305 (READ_RREG(REG_SP)), /* behavior */ 306 () 307) 308 309DEF_MACRO( 310 fREAD_LC0, /* read loop count */ 311 (READ_RREG(REG_LC0)), /* behavior */ 312 () 313) 314 315DEF_MACRO( 316 fREAD_LC1, /* read loop count */ 317 (READ_RREG(REG_LC1)), /* behavior */ 318 () 319) 320 321DEF_MACRO( 322 fREAD_SA0, /* read start addr */ 323 (READ_RREG(REG_SA0)), /* behavior */ 324 () 325) 326 327DEF_MACRO( 328 fREAD_SA1, /* read start addr */ 329 (READ_RREG(REG_SA1)), /* behavior */ 330 () 331) 332 333 334DEF_MACRO( 335 fREAD_FP, /* read frame pointer */ 336 (READ_RREG(REG_FP)), /* behavior */ 337 () 338) 339 340DEF_MACRO( 341 fREAD_GP, /* read global pointer */ 342 (insn->extension_valid ? 0 : READ_RREG(REG_GP)), /* behavior */ 343 () 344) 345 346DEF_MACRO( 347 fREAD_PC, /* read PC */ 348 (READ_RREG(REG_PC)), /* behavior */ 349 () 350) 351 352DEF_MACRO( 353 fREAD_NPC, /* read next PC */ 354 (thread->next_PC & (0xfffffffe)), /* behavior */ 355 () 356) 357 358DEF_MACRO( 359 fREAD_P0, /* read Predicate 0 */ 360 (READ_PREG(0)), /* behavior */ 361 () 362) 363 364DEF_MACRO( 365 fREAD_P3, /* read Predicate 3 */ 366 (READ_PREG(3)), /* behavior */ 367 () 368) 369 370DEF_MACRO( 371 fCHECK_PCALIGN, 372 if (((A) & PCALIGN_MASK)) { 373 register_error_exception(thread,PRECISE_CAUSE_PC_NOT_ALIGNED,thread->Regs[REG_BADVA0],thread->Regs[REG_BADVA1],GET_SSR_FIELD(SSR_BVS),GET_SSR_FIELD(SSR_V0),GET_SSR_FIELD(SSR_V1),0); 374 }, 375 () 376) 377 378DEF_MACRO( 379 fWRITE_NPC, /* write next PC */ 380 if (!thread->branch_taken) { 381 if (A != thread->next_PC) { 382 thread->next_pkt_guess=thread->last_pkt->taken_ptr; 383 } 384 fCHECK_PCALIGN(A); 385 thread->branched = 1; thread->branch_taken = 1; thread->next_PC = A; \ 386 thread->branch_offset = insn->encoding_offset; thread->branch_opcode = insn->opcode; 387 }, /* behavior */ 388 (A_COF) 389) 390 391DEF_MACRO( 392 fBRANCH, 393 fWRITE_NPC(LOC); fCOF_CALLBACK(LOC,TYPE), 394 () 395) 396 397DEF_MACRO( 398 fJUMPR, /* A jumpr has executed */ 399 {fBRANCH(TARGET,COF_TYPE_JUMPR);}, 400 (A_INDIRECT) 401) 402 403DEF_MACRO( 404 fHINTJR, /* A hintjr instruction has executed */ 405 { }, 406) 407 408DEF_MACRO( 409 fCALL, /* Do a call */ 410 if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALL);}, 411 (A_COF,A_IMPLICIT_WRITES_LR,A_CALL) 412) 413 414DEF_MACRO( 415 fCALLR, /* Do a call Register */ 416 if (!thread->branch_taken) {fBP_RAS_CALL(A); fWRITE_LR(fREAD_NPC()); fBRANCH(A,COF_TYPE_CALLR);}, 417 (A_COF,A_IMPLICIT_WRITES_LR,A_CALL) 418) 419 420DEF_MACRO( 421 fWRITE_LOOP_REGS0, /* write ln,sa,ea,lc */ 422 {WRITE_RREG(REG_LC0,COUNT); 423 WRITE_RREG(REG_SA0,START);}, 424 (A_IMPLICIT_WRITES_LC0,A_IMPLICIT_WRITES_SA0) 425) 426 427DEF_MACRO( 428 fWRITE_LOOP_REGS1, /* write ln,sa,ea,lc */ 429 {WRITE_RREG(REG_LC1,COUNT); 430 WRITE_RREG(REG_SA1,START);}, 431 (A_IMPLICIT_WRITES_LC1,A_IMPLICIT_WRITES_SA1) 432) 433 434DEF_MACRO( 435 fWRITE_LC0, 436 WRITE_RREG(REG_LC0,VAL), 437 (A_IMPLICIT_WRITES_LC0) 438) 439 440DEF_MACRO( 441 fWRITE_LC1, 442 WRITE_RREG(REG_LC1,VAL), 443 (A_IMPLICIT_WRITES_LC1) 444) 445 446DEF_MACRO( 447 fCARRY_FROM_ADD, 448 carry_from_add64(A,B,C), 449 /* NOTHING */ 450) 451 452DEF_MACRO( 453 fSET_OVERFLOW, 454 SET_USR_FIELD(USR_OVF,1), 455 () 456) 457 458DEF_MACRO( 459 fSET_LPCFG, 460 SET_USR_FIELD(USR_LPCFG,(VAL)), 461 () 462) 463 464 465DEF_MACRO( 466 fGET_LPCFG, 467 (GET_USR_FIELD(USR_LPCFG)), 468 () 469) 470 471 472 473DEF_MACRO( 474 fWRITE_P0, /* write Predicate 0 */ 475 WRITE_PREG(0,VAL), /* behavior */ 476 (A_IMPLICIT_WRITES_P0) 477) 478 479DEF_MACRO( 480 fWRITE_P1, /* write Predicate 0 */ 481 WRITE_PREG(1,VAL), /* behavior */ 482 (A_IMPLICIT_WRITES_P1) 483) 484 485DEF_MACRO( 486 fWRITE_P2, /* write Predicate 0 */ 487 WRITE_PREG(2,VAL), /* behavior */ 488 (A_IMPLICIT_WRITES_P2) 489) 490 491DEF_MACRO( 492 fWRITE_P3, /* write Predicate 0 */ 493 WRITE_PREG(3,VAL), /* behavior */ 494 (A_IMPLICIT_WRITES_P3) 495) 496 497DEF_MACRO( 498 fPART1, /* write Predicate 0 */ 499 if (insn->part1) { WORK; return; }, /* behavior */ 500 /* optional attributes */ 501) 502 503 504/*************************************/ 505/* Casting, Sign-Zero extension, etc */ 506/*************************************/ 507 508DEF_MACRO( 509 fCAST4u, /* macro name */ 510 ((size4u_t)(A)), /* behavior */ 511 /* optional attributes */ 512) 513 514DEF_MACRO( 515 fCAST4s, /* macro name */ 516 ((size4s_t)(A)), /* behavior */ 517 /* optional attributes */ 518) 519 520DEF_MACRO( 521 fCAST8u, /* macro name */ 522 ((size8u_t)(A)), /* behavior */ 523 /* optional attributes */ 524) 525 526DEF_MACRO( 527 fCAST8s, /* macro name */ 528 ((size8s_t)(A)), /* behavior */ 529 /* optional attributes */ 530) 531 532DEF_MACRO( 533 fCAST4_4s, /* macro name */ 534 ((size4s_t)(A)), 535 /* optional attributes */ 536) 537 538DEF_MACRO( 539 fCAST4_4u, /* macro name */ 540 ((size4u_t)(A)), 541 /* optional attributes */ 542) 543 544 545DEF_MACRO( 546 fCAST4_8s, /* macro name */ 547 ((size8s_t)((size4s_t)(A))), 548 /* optional attributes */ 549) 550 551DEF_MACRO( 552 fCAST4_8u, /* macro name */ 553 ((size8u_t)((size4u_t)(A))), 554 /* optional attributes */ 555) 556 557DEF_MACRO( 558 fCAST8_8s, /* macro name */ 559 ((size8s_t)(A)), 560 /* optional attributes */ 561) 562 563DEF_MACRO( 564 fCAST8_8u, /* macro name */ 565 ((size8u_t)(A)), 566 /* optional attributes */ 567) 568 569DEF_MACRO( 570 fCAST2_8s, /* macro name */ 571 ((size8s_t)((size2s_t)(A))), 572 /* optional attributes */ 573) 574DEF_MACRO( 575 fCAST2_8u, /* macro name */ 576 ((size8u_t)((size2u_t)(A))), 577 /* optional attributes */ 578) 579 580DEF_MACRO( 581 fZE8_16, /* zero-extend 8 to 16 */ 582 ((size2s_t)((size1u_t)(A))), 583 /* optional attributes */ 584) 585DEF_MACRO( 586 fSE8_16, /* sign-extend 8 to 16 */ 587 ((size2s_t)((size1s_t)(A))), 588 /* optional attributes */ 589) 590 591 592DEF_MACRO( 593 fSE16_32, /* sign-extend 16 to 32 */ 594 ((size4s_t)((size2s_t)(A))), /* behavior */ 595 /* optional attributes */ 596) 597 598DEF_MACRO( 599 fZE16_32, /* zero-extend 16 to 32 */ 600 ((size4u_t)((size2u_t)(A))), /* behavior */ 601 /* optional attributes */ 602) 603 604DEF_MACRO( 605 fSE32_64, 606 ( (size8s_t)((size4s_t)(A)) ), /* behavior */ 607 /* optional attributes */ 608) 609 610DEF_MACRO( 611 fZE32_64, 612 ( (size8u_t)((size4u_t)(A)) ), /* behavior */ 613 /* optional attributes */ 614) 615 616DEF_MACRO( 617 fSE8_32, /* sign-extend 8 to 32 */ 618 ((size4s_t)((size1s_t)(A))), 619 /* optional attributes */ 620) 621 622DEF_MACRO( 623 fZE8_32, /* zero-extend 8 to 32 */ 624 ((size4s_t)((size1u_t)(A))), 625 /* optional attributes */ 626) 627 628/*************************************/ 629/* DSP arithmetic support */ 630/************************************/ 631DEF_MACRO( 632 fMPY8UU, /* multiply half integer */ 633 (int)(fZE8_16(A)*fZE8_16(B)), /* behavior */ 634 () 635) 636DEF_MACRO( 637 fMPY8US, /* multiply half integer */ 638 (int)(fZE8_16(A)*fSE8_16(B)), /* behavior */ 639 () 640) 641DEF_MACRO( 642 fMPY8SU, /* multiply half integer */ 643 (int)(fSE8_16(A)*fZE8_16(B)), /* behavior */ 644 () 645) 646 647DEF_MACRO( 648 fMPY8SS, /* multiply half integer */ 649 (int)((short)(A)*(short)(B)), /* behavior */ 650 () 651) 652 653DEF_MACRO( 654 fMPY16SS, /* multiply half integer */ 655 fSE32_64(fSE16_32(A)*fSE16_32(B)), /* behavior */ 656 () 657) 658 659DEF_MACRO( 660 fMPY16UU, /* multiply unsigned half integer */ 661 fZE32_64(fZE16_32(A)*fZE16_32(B)), /* behavior */ 662 () 663) 664 665DEF_MACRO( 666 fMPY16SU, /* multiply half integer */ 667 fSE32_64(fSE16_32(A)*fZE16_32(B)), /* behavior */ 668 () 669) 670 671DEF_MACRO( 672 fMPY16US, /* multiply half integer */ 673 fMPY16SU(B,A), 674 () 675) 676 677DEF_MACRO( 678 fMPY32SS, /* multiply half integer */ 679 (fSE32_64(A)*fSE32_64(B)), /* behavior */ 680 () 681) 682 683DEF_MACRO( 684 fMPY32UU, /* multiply half integer */ 685 (fZE32_64(A)*fZE32_64(B)), /* behavior */ 686 () 687) 688 689DEF_MACRO( 690 fMPY32SU, /* multiply half integer */ 691 (fSE32_64(A)*fZE32_64(B)), /* behavior */ 692 () 693) 694 695DEF_MACRO( 696 fMPY3216SS, /* multiply mixed precision */ 697 (fSE32_64(A)*fSXTN(16,64,B)), /* behavior */ 698 () 699) 700 701DEF_MACRO( 702 fMPY3216SU, /* multiply mixed precision */ 703 (fSE32_64(A)*fZXTN(16,64,B)), /* behavior */ 704 () 705) 706 707DEF_MACRO( 708 fROUND, /* optional rounding */ 709 (A+0x8000), 710 /* optional attributes */ 711) 712 713DEF_MACRO( 714 fCLIP, /* optional rounding */ 715 { size4s_t maxv = (1<<U)-1; 716 size4s_t minv = -(1<<U); 717 DST = fMIN(maxv,fMAX(SRC,minv)); 718 }, 719 /* optional attributes */ 720) 721 722DEF_MACRO( 723 fCRND, /* optional rounding */ 724 ((((A)&0x3)==0x3)?((A)+1):((A))), 725 /* optional attributes */ 726) 727 728DEF_MACRO( 729 fRNDN, /* Rounding to a boundary */ 730 ((((N)==0)?(A):(((fSE32_64(A))+(1<<((N)-1)))))), 731 /* optional attributes */ 732) 733 734DEF_MACRO( 735 fCRNDN, /* Rounding to a boundary */ 736 (conv_round(A,N)), 737 /* optional attributes */ 738) 739 740DEF_MACRO( 741 fADD128, /* Rounding to a boundary */ 742 (add128(A, B)), 743 /* optional attributes */ 744) 745DEF_MACRO( 746 fSUB128, /* Rounding to a boundary */ 747 (sub128(A, B)), 748 /* optional attributes */ 749) 750DEF_MACRO( 751 fSHIFTR128, /* Rounding to a boundary */ 752 (shiftr128(A, B)), 753 /* optional attributes */ 754) 755 756DEF_MACRO( 757 fSHIFTL128, /* Rounding to a boundary */ 758 (shiftl128(A, B)), 759 /* optional attributes */ 760) 761 762DEF_MACRO( 763 fAND128, /* Rounding to a boundary */ 764 (and128(A, B)), 765 /* optional attributes */ 766) 767 768DEF_MACRO( 769 fCAST8S_16S, /* Rounding to a boundary */ 770 (cast8s_to_16s(A)), 771 /* optional attributes */ 772) 773DEF_MACRO( 774 fCAST16S_8S, /* Rounding to a boundary */ 775 (cast16s_to_8s(A)), 776 /* optional attributes */ 777) 778 779DEF_MACRO( 780 fEA_RI, /* Calculate EA with Register + Immediate Offset */ 781 do { EA=REG+IMM; fDOCHKPAGECROSS(REG,EA); } while (0), 782 () 783) 784 785DEF_MACRO( 786 fEA_RRs, /* Calculate EA with Register + Registers scaled Offset */ 787 do { EA=REG+(REG2<<SCALE); fDOCHKPAGECROSS(REG,EA); } while (0), 788 () 789) 790 791DEF_MACRO( 792 fEA_IRs, /* Calculate EA with Immediate + Registers scaled Offset */ 793 do { EA=IMM+(REG<<SCALE); fDOCHKPAGECROSS(IMM,EA); } while (0), 794 () 795) 796 797DEF_MACRO( 798 fEA_IMM, /* Calculate EA with Immediate */ 799 EA=IMM, 800 () 801) 802 803DEF_MACRO( 804 fEA_REG, /* Calculate EA with REGISTER */ 805 EA=REG, 806 () 807) 808 809DEF_MACRO( 810 fEA_GPI, /* Calculate EA with Global Poitner + Immediate */ 811 do { EA=fREAD_GP()+IMM; fGP_DOCHKPAGECROSS(fREAD_GP(),EA); } while (0), 812 () 813) 814 815DEF_MACRO( 816 fPM_I, /* Post Modify Register by Immediate*/ 817 do { REG = REG + IMM; } while (0), 818 () 819) 820 821DEF_MACRO( 822 fPM_M, /* Post Modify Register by M register */ 823 do { REG = REG + MVAL; } while (0), 824 () 825) 826 827DEF_MACRO( 828 fSCALE, /* scale by N */ 829 (((size8s_t)(A))<<N), 830 /* optional attributes */ 831) 832 833DEF_MACRO( 834 fSATW, /* saturating to 32-bits*/ 835 fSATN(32,((long long)A)), 836 () 837) 838 839DEF_MACRO( 840 fSAT, /* saturating to 32-bits*/ 841 fSATN(32,(A)), 842 () 843) 844 845DEF_MACRO( 846 fSAT_ORIG_SHL, /* Saturating to 32-bits, with original value, for shift left */ 847 ((((size4s_t)((fSAT(A)) ^ ((size4s_t)(ORIG_REG)))) < 0) ? 848 fSATVALN(32,((size4s_t)(ORIG_REG))) : 849 ((((ORIG_REG) > 0) && ((A) == 0)) ? 850 fSATVALN(32,(ORIG_REG)) : 851 fSAT(A))), 852 () 853) 854 855DEF_MACRO( 856 fPASS, 857 A, 858) 859 860DEF_MACRO( 861 fRND, /* saturating to 32-bits*/ 862 (((A)+1)>>1), 863) 864 865 866DEF_MACRO( 867 fBIDIR_SHIFTL, 868 (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) >> ((-(SHAMT))-1)) >>1) : (fCAST##REGSTYPE(SRC) << (SHAMT))), 869 () 870) 871 872DEF_MACRO( 873 fBIDIR_ASHIFTL, 874 fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##s), 875 () 876) 877 878DEF_MACRO( 879 fBIDIR_LSHIFTL, 880 fBIDIR_SHIFTL(SRC,SHAMT,REGSTYPE##u), 881 () 882) 883 884DEF_MACRO( 885 fBIDIR_ASHIFTL_SAT, 886 (((SHAMT) < 0) ? ((fCAST##REGSTYPE##s(SRC) >> ((-(SHAMT))-1)) >>1) : fSAT_ORIG_SHL(fCAST##REGSTYPE##s(SRC) << (SHAMT),(SRC))), 887 () 888) 889 890 891DEF_MACRO( 892 fBIDIR_SHIFTR, 893 (((SHAMT) < 0) ? ((fCAST##REGSTYPE(SRC) << ((-(SHAMT))-1)) << 1) : (fCAST##REGSTYPE(SRC) >> (SHAMT))), 894 () 895) 896 897DEF_MACRO( 898 fBIDIR_ASHIFTR, 899 fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##s), 900 () 901) 902 903DEF_MACRO( 904 fBIDIR_LSHIFTR, 905 fBIDIR_SHIFTR(SRC,SHAMT,REGSTYPE##u), 906 () 907) 908 909DEF_MACRO( 910 fBIDIR_ASHIFTR_SAT, 911 (((SHAMT) < 0) ? fSAT_ORIG_SHL((fCAST##REGSTYPE##s(SRC) << ((-(SHAMT))-1)) << 1,(SRC)) : (fCAST##REGSTYPE##s(SRC) >> (SHAMT))), 912 () 913) 914 915DEF_MACRO( 916 fASHIFTR, 917 (fCAST##REGSTYPE##s(SRC) >> (SHAMT)), 918 /* */ 919) 920 921DEF_MACRO( 922 fLSHIFTR, 923 (((SHAMT) >= 64)?0:(fCAST##REGSTYPE##u(SRC) >> (SHAMT))), 924 /* */ 925) 926 927DEF_MACRO( 928 fROTL, 929 (((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) << (SHAMT)) | \ 930 ((fCAST##REGSTYPE##u(SRC) >> ((sizeof(SRC)*8)-(SHAMT)))))), 931 /* */ 932) 933 934DEF_MACRO( 935 fROTR, 936 (((SHAMT)==0) ? (SRC) : ((fCAST##REGSTYPE##u(SRC) >> (SHAMT)) | \ 937 ((fCAST##REGSTYPE##u(SRC) << ((sizeof(SRC)*8)-(SHAMT)))))), 938 /* */ 939) 940 941DEF_MACRO( 942 fASHIFTL, 943 (((SHAMT) >= 64)?0:(fCAST##REGSTYPE##s(SRC) << (SHAMT))), 944 /* */ 945) 946 947/*************************************/ 948/* Floating-Point Support */ 949/************************************/ 950 951DEF_MACRO( 952 fFLOAT, /* name */ 953 ({ union { float f; size4u_t i; } _fipun; _fipun.i = (A); _fipun.f; }), /* behavior */ 954 (A_FPOP) 955) 956 957DEF_MACRO( 958 fUNFLOAT, /* multiply half integer */ 959 ({ union { float f; size4u_t i; } _fipun; _fipun.f = (A); isnan(_fipun.f) ? 0xFFFFFFFFU : _fipun.i; }), /* behavior */ 960 (A_FPOP) 961) 962 963DEF_MACRO( 964 fSFNANVAL, 965 0xffffffff, 966 () 967) 968 969DEF_MACRO( 970 fSFINFVAL, 971 (((A) & 0x80000000) | 0x7f800000), 972 () 973) 974 975DEF_MACRO( 976 fSFONEVAL, 977 (((A) & 0x80000000) | fUNFLOAT(1.0)), 978 () 979) 980 981DEF_MACRO( 982 fCHECKSFNAN, 983 do { 984 if (isnan(fFLOAT(A))) { 985 if ((fGETBIT(22,A)) == 0) fRAISEFLAGS(FE_INVALID); 986 DST = fSFNANVAL(); 987 } 988 } while (0), 989 () 990) 991 992DEF_MACRO( 993 fCHECKSFNAN3, 994 do { 995 fCHECKSFNAN(DST,A); 996 fCHECKSFNAN(DST,B); 997 fCHECKSFNAN(DST,C); 998 } while (0), 999 () 1000) 1001 1002DEF_MACRO( 1003 fSF_BIAS, 1004 127, 1005 () 1006) 1007 1008DEF_MACRO( 1009 fSF_MANTBITS, 1010 23, 1011 () 1012) 1013 1014DEF_MACRO( 1015 fSF_MUL_POW2, 1016 (fUNFLOAT(fFLOAT(A) * fFLOAT((fSF_BIAS() + (B)) << fSF_MANTBITS()))), 1017 () 1018) 1019 1020DEF_MACRO( 1021 fSF_GETEXP, 1022 (((A) >> fSF_MANTBITS()) & 0xff), 1023 () 1024) 1025 1026DEF_MACRO( 1027 fSF_MAXEXP, 1028 (254), 1029 () 1030) 1031 1032DEF_MACRO( 1033 fSF_RECIP_COMMON, 1034 arch_sf_recip_common(&N,&D,&O,&A), 1035 (A_FPOP) 1036) 1037 1038DEF_MACRO( 1039 fSF_INVSQRT_COMMON, 1040 arch_sf_invsqrt_common(&N,&O,&A), 1041 (A_FPOP) 1042) 1043 1044DEF_MACRO( 1045 fFMAFX, 1046 internal_fmafx(A,B,C,fSXTN(8,64,ADJ)), 1047 () 1048) 1049 1050DEF_MACRO( 1051 fFMAF, 1052 internal_fmafx(A,B,C,0), 1053 () 1054) 1055 1056DEF_MACRO( 1057 fSFMPY, 1058 internal_mpyf(A,B), 1059 () 1060) 1061 1062DEF_MACRO( 1063 fMAKESF, 1064 ((((SIGN) & 1) << 31) | (((EXP) & 0xff) << fSF_MANTBITS()) | 1065 ((MANT) & ((1<<fSF_MANTBITS())-1))), 1066 () 1067) 1068 1069 1070DEF_MACRO( 1071 fDOUBLE, /* multiply half integer */ 1072 ({ union { double f; size8u_t i; } _fipun; _fipun.i = (A); _fipun.f; }), /* behavior */ 1073 (A_FPOP) 1074) 1075 1076DEF_MACRO( 1077 fUNDOUBLE, /* multiply half integer */ 1078 ({ union { double f; size8u_t i; } _fipun; _fipun.f = (A); isnan(_fipun.f) ? 0xFFFFFFFFFFFFFFFFULL : _fipun.i; }), /* behavior */ 1079 (A_FPOP) 1080) 1081 1082DEF_MACRO( 1083 fDFNANVAL, 1084 0xffffffffffffffffULL, 1085 () 1086) 1087 1088DEF_MACRO( 1089 fDF_ISNORMAL, 1090 (fpclassify(fDOUBLE(X)) == FP_NORMAL), 1091 () 1092) 1093 1094DEF_MACRO( 1095 fDF_ISDENORM, 1096 (fpclassify(fDOUBLE(X)) == FP_SUBNORMAL), 1097 () 1098) 1099 1100DEF_MACRO( 1101 fDF_ISBIG, 1102 (fDF_GETEXP(X) >= 512), 1103 () 1104) 1105 1106DEF_MACRO( 1107 fDF_MANTBITS, 1108 52, 1109 () 1110) 1111 1112DEF_MACRO( 1113 fDF_GETEXP, 1114 (((A) >> fDF_MANTBITS()) & 0x7ff), 1115 () 1116) 1117 1118DEF_MACRO( 1119 fFMA, 1120 internal_fma(A,B,C), 1121 /* nothing */ 1122) 1123 1124DEF_MACRO( 1125 fDF_MPY_HH, 1126 internal_mpyhh(A,B,ACC), 1127 /* nothing */ 1128) 1129 1130DEF_MACRO( 1131 fFPOP_START, 1132 arch_fpop_start(thread), 1133 /* nothing */ 1134) 1135 1136DEF_MACRO( 1137 fFPOP_END, 1138 arch_fpop_end(thread), 1139 /* nothing */ 1140) 1141 1142DEF_MACRO( 1143 fFPSETROUND_NEAREST, 1144 fesetround(FE_TONEAREST), 1145 /* nothing */ 1146) 1147 1148DEF_MACRO( 1149 fFPSETROUND_CHOP, 1150 fesetround(FE_TOWARDZERO), 1151 /* nothing */ 1152) 1153 1154DEF_MACRO( 1155 fFPCANCELFLAGS, 1156 feclearexcept(FE_ALL_EXCEPT), 1157 /* nothing */ 1158) 1159 1160DEF_MACRO( 1161 fISINFPROD, 1162 ((isinf(A) && isinf(B)) || 1163 (isinf(A) && isfinite(B) && ((B) != 0.0)) || 1164 (isinf(B) && isfinite(A) && ((A) != 0.0))), 1165 /* nothing */ 1166) 1167 1168DEF_MACRO( 1169 fISZEROPROD, 1170 ((((A) == 0.0) && isfinite(B)) || (((B) == 0.0) && isfinite(A))), 1171 /* nothing */ 1172) 1173 1174DEF_MACRO( 1175 fRAISEFLAGS, 1176 arch_raise_fpflag(A), 1177 /* NOTHING */ 1178) 1179 1180DEF_MACRO( 1181 fDF_MAX, 1182 (((A)==(B)) 1183 ? fDOUBLE(fUNDOUBLE(A) & fUNDOUBLE(B)) 1184 : fmax(A,B)), 1185 (A_FPOP) 1186) 1187 1188DEF_MACRO( 1189 fDF_MIN, 1190 (((A)==(B)) 1191 ? fDOUBLE(fUNDOUBLE(A) | fUNDOUBLE(B)) 1192 : fmin(A,B)), 1193 (A_FPOP) 1194) 1195 1196DEF_MACRO( 1197 fSF_MAX, 1198 (((A)==(B)) 1199 ? fFLOAT(fUNFLOAT(A) & fUNFLOAT(B)) 1200 : fmaxf(A,B)), 1201 (A_FPOP) 1202) 1203 1204DEF_MACRO( 1205 fSF_MIN, 1206 (((A)==(B)) 1207 ? fFLOAT(fUNFLOAT(A) | fUNFLOAT(B)) 1208 : fminf(A,B)), 1209 (A_FPOP) 1210) 1211 1212/*************************************/ 1213/* Load/Store support */ 1214/*************************************/ 1215 1216DEF_MACRO(fLOAD, 1217 { DST = (size##SIZE##SIGN##_t)MEM_LOAD##SIZE(thread,EA,insn); }, 1218 (A_LOAD,A_MEMLIKE) 1219) 1220 1221DEF_MACRO(fMEMOP, 1222 { memop##SIZE##_##FNTYPE(thread,EA,VALUE); }, 1223 (A_LOAD,A_STORE,A_MEMLIKE) 1224) 1225 1226DEF_MACRO(fGET_FRAMEKEY, 1227 READ_RREG(REG_FRAMEKEY), 1228 () 1229) 1230 1231DEF_MACRO(fFRAME_SCRAMBLE, 1232 ((VAL) ^ (fCAST8u(fGET_FRAMEKEY()) << 32)), 1233 /* ATTRIBS */ 1234) 1235 1236DEF_MACRO(fFRAME_UNSCRAMBLE, 1237 fFRAME_SCRAMBLE(VAL), 1238 /* ATTRIBS */ 1239) 1240 1241DEF_MACRO(fFRAMECHECK, 1242 sys_check_framelimit(thread,ADDR,EA), 1243 () 1244) 1245 1246DEF_MACRO(fLOAD_LOCKED, 1247 { DST = (size##SIZE##SIGN##_t)mem_load_locked(thread,EA,SIZE,insn); }, 1248 (A_LOAD,A_MEMLIKE) 1249) 1250 1251DEF_MACRO(fSTORE, 1252 { MEM_STORE##SIZE(thread,EA,SRC,insn); }, 1253 (A_STORE,A_MEMLIKE) 1254) 1255 1256 1257DEF_MACRO(fSTORE_LOCKED, 1258 { PRED = (mem_store_conditional(thread,EA,SRC,SIZE,insn) ? 0xff : 0); }, 1259 (A_STORE,A_MEMLIKE) 1260) 1261 1262/*************************************/ 1263/* Functions to help with bytes */ 1264/*************************************/ 1265 1266DEF_MACRO(fGETBYTE, 1267 ((size1s_t)((SRC>>((N)*8))&0xff)), 1268 /* nothing */ 1269) 1270 1271DEF_MACRO(fGETUBYTE, 1272 ((size1u_t)((SRC>>((N)*8))&0xff)), 1273 /* nothing */ 1274) 1275 1276DEF_MACRO(fSETBYTE, 1277 { 1278 DST = (DST & ~(0x0ffLL<<((N)*8))) | (((size8u_t)((VAL) & 0x0ffLL)) << ((N)*8)); 1279 }, 1280 /* nothing */ 1281) 1282 1283DEF_MACRO(fGETHALF, 1284 ((size2s_t)((SRC>>((N)*16))&0xffff)), 1285 /* nothing */ 1286) 1287 1288DEF_MACRO(fGETUHALF, 1289 ((size2u_t)((SRC>>((N)*16))&0xffff)), 1290 /* nothing */ 1291) 1292 1293DEF_MACRO(fSETHALF, 1294 { 1295 DST = (DST & ~(0x0ffffLL<<((N)*16))) | (((size8u_t)((VAL) & 0x0ffff)) << ((N)*16)); 1296 }, 1297 /* nothing */ 1298) 1299 1300 1301 1302DEF_MACRO(fGETWORD, 1303 ((size8s_t)((size4s_t)((SRC>>((N)*32))&0x0ffffffffLL))), 1304 /* nothing */ 1305) 1306 1307DEF_MACRO(fGETUWORD, 1308 ((size8u_t)((size4u_t)((SRC>>((N)*32))&0x0ffffffffLL))), 1309 /* nothing */ 1310) 1311 1312DEF_MACRO(fSETWORD, 1313 { 1314 DST = (DST & ~(0x0ffffffffLL<<((N)*32))) | (((VAL) & 0x0ffffffffLL) << ((N)*32)); 1315 }, 1316 /* nothing */ 1317) 1318 1319DEF_MACRO(fSETBIT, 1320 { 1321 DST = (DST & ~(1ULL<<(N))) | (((size8u_t)(VAL))<<(N)); 1322 }, 1323 /* nothing */ 1324) 1325 1326DEF_MACRO(fGETBIT, 1327 (((SRC)>>N)&1), 1328 /* nothing */ 1329) 1330 1331 1332DEF_MACRO(fSETBITS, 1333 do { 1334 int j; 1335 for (j=LO;j<=HI;j++) { 1336 fSETBIT(j,DST,VAL); 1337 } 1338 } while (0), 1339 /* nothing */ 1340) 1341 1342/*************************************/ 1343/* Used for parity, etc........ */ 1344/*************************************/ 1345DEF_MACRO(fCOUNTONES_4, 1346 count_ones_4(VAL), 1347 /* nothing */ 1348) 1349 1350DEF_MACRO(fCOUNTONES_8, 1351 count_ones_8(VAL), 1352 /* nothing */ 1353) 1354 1355DEF_MACRO(fBREV_8, 1356 reverse_bits_8(VAL), 1357 /* nothing */ 1358) 1359 1360DEF_MACRO(fBREV_4, 1361 reverse_bits_4(VAL), 1362 /* nothing */ 1363) 1364 1365DEF_MACRO(fCL1_8, 1366 count_leading_ones_8(VAL), 1367 /* nothing */ 1368) 1369 1370DEF_MACRO(fCL1_4, 1371 count_leading_ones_4(VAL), 1372 /* nothing */ 1373) 1374 1375DEF_MACRO(fINTERLEAVE, 1376 interleave(ODD,EVEN), 1377 /* nothing */ 1378) 1379 1380DEF_MACRO(fDEINTERLEAVE, 1381 deinterleave(MIXED), 1382 /* nothing */ 1383) 1384 1385DEF_MACRO(fHIDE, 1386 A, 1387 () 1388) 1389 1390DEF_MACRO(fCONSTLL, 1391 A##LL, 1392) 1393 1394/* Do the things in the parens, but don't print the parens. */ 1395DEF_MACRO(fECHO, 1396 (A), 1397 /* nothing */ 1398) 1399 1400 1401/********************************************/ 1402/* OS interface and stop/wait */ 1403/********************************************/ 1404 1405DEF_MACRO(fPAUSE, 1406 {sys_pause(thread, insn->slot, IMM);}, 1407 () 1408) 1409 1410DEF_MACRO(fTRAP, 1411 warn("Trap NPC=%x ",fREAD_NPC()); 1412 warn("Trap exception, PCYCLE=%lld TYPE=%d NPC=%x IMM=0x%x",thread->processor_ptr->pstats[pcycles],TRAPTYPE,fREAD_NPC(),IMM); 1413 register_trap_exception(thread,fREAD_NPC(),TRAPTYPE,IMM);, 1414 () 1415) 1416 1417DEF_MACRO(fALIGN_REG_FIELD_VALUE, 1418 ((VAL)<<reg_field_info[FIELD].offset), 1419 /* */ 1420) 1421 1422DEF_MACRO(fGET_REG_FIELD_MASK, 1423 (((1<<reg_field_info[FIELD].width)-1)<<reg_field_info[FIELD].offset), 1424 /* */ 1425) 1426 1427DEF_MACRO(fREAD_REG_FIELD, 1428 fEXTRACTU_BITS(thread->Regs[REG_##REG], 1429 reg_field_info[FIELD].width, 1430 reg_field_info[FIELD].offset), 1431 /* ATTRIBS */ 1432) 1433 1434DEF_MACRO(fGET_FIELD, 1435 fEXTRACTU_BITS(VAL, 1436 reg_field_info[FIELD].width, 1437 reg_field_info[FIELD].offset), 1438 /* ATTRIBS */ 1439) 1440 1441DEF_MACRO(fSET_FIELD, 1442 fINSERT_BITS(VAL, 1443 reg_field_info[FIELD].width, 1444 reg_field_info[FIELD].offset, 1445 (NEWVAL)), 1446 /* ATTRIBS */ 1447) 1448 1449/********************************************/ 1450/* Cache Management */ 1451/********************************************/ 1452 1453DEF_MACRO(fBARRIER, 1454 { 1455 sys_barrier(thread, insn->slot); 1456 }, 1457 () 1458) 1459 1460DEF_MACRO(fSYNCH, 1461 { 1462 sys_sync(thread, insn->slot); 1463 }, 1464 () 1465) 1466 1467DEF_MACRO(fISYNC, 1468 { 1469 sys_isync(thread, insn->slot); 1470 }, 1471 () 1472) 1473 1474 1475DEF_MACRO(fDCFETCH, 1476 sys_dcfetch(thread, (REG), insn->slot), 1477 (A_MEMLIKE) 1478) 1479 1480DEF_MACRO(fICINVA, 1481 { 1482 arch_internal_flush(thread->processor_ptr, 0, 0xffffffff); 1483 sys_icinva(thread, (REG),insn->slot); 1484 }, 1485 (A_ICINVA) 1486) 1487 1488DEF_MACRO(fL2FETCH, 1489 sys_l2fetch(thread, ADDR,HEIGHT,WIDTH,STRIDE,FLAGS, insn->slot), 1490 (A_MEMLIKE,A_L2FETCH) 1491) 1492 1493DEF_MACRO(fDCCLEANA, 1494 sys_dccleana(thread, (REG)), 1495 (A_MEMLIKE) 1496) 1497 1498DEF_MACRO(fDCCLEANINVA, 1499 sys_dccleaninva(thread, (REG), insn->slot), 1500 (A_MEMLIKE,A_DCCLEANINVA) 1501) 1502 1503DEF_MACRO(fDCZEROA, 1504 sys_dczeroa(thread, (REG)), 1505 (A_MEMLIKE) 1506) 1507 1508DEF_MACRO(fCHECKFORPRIV, 1509 {sys_check_privs(thread); if (EXCEPTION_DETECTED) return; }, 1510 () 1511) 1512 1513DEF_MACRO(fCHECKFORGUEST, 1514 {sys_check_guest(thread); if (EXCEPTION_DETECTED) return; }, 1515 () 1516) 1517 1518DEF_MACRO(fBRANCH_SPECULATE_STALL, 1519 { 1520 sys_speculate_branch_stall(thread, insn->slot, JUMP_COND(JUMP_PRED_SET), 1521 SPEC_DIR, 1522 DOTNEWVAL, 1523 HINTBITNUM, 1524 STRBITNUM, 1525 0, 1526 thread->last_pkt->pkt_has_dual_jump, 1527 insn->is_2nd_jump, 1528 (thread->fetch_access.vaddr + insn->encoding_offset*4)); 1529 }, 1530 () 1531) 1532