1;; Instruction formats. 2(type MInst 3 (enum 4 ;; A no-op of zero size. 5 (Nop0) 6 7 ;; A no-op of size two bytes. 8 (Nop2) 9 10 ;; An ALU operation with two register sources and a register destination. 11 (AluRRR 12 (alu_op ALUOp) 13 (rd WritableReg) 14 (rn Reg) 15 (rm Reg)) 16 17 ;; An ALU operation with a register source and a signed 16-bit 18 ;; immediate source, and a separate register destination. 19 (AluRRSImm16 20 (alu_op ALUOp) 21 (rd WritableReg) 22 (rn Reg) 23 (imm i16)) 24 25 ;; An ALU operation with a register in-/out operand and 26 ;; a second register source. 27 (AluRR 28 (alu_op ALUOp) 29 (rd WritableReg) 30 ;; Input side of `rd`. `rd` is constrained to reuse `ri`'s 31 ;; allocation during regalloc. Hence, we have SSA form here (ri 32 ;; is strictly a use, rd is strictly a def) and it becomes a 33 ;; modified-reg form when encoded. 34 (ri Reg) 35 (rm Reg)) 36 37 ;; An ALU operation with a register in-/out operand and 38 ;; a memory source. 39 (AluRX 40 (alu_op ALUOp) 41 (rd WritableReg) 42 (ri Reg) 43 (mem MemArg)) 44 45 ;; An ALU operation with a register in-/out operand and a signed 16-bit 46 ;; immediate source. 47 (AluRSImm16 48 (alu_op ALUOp) 49 (rd WritableReg) 50 (ri Reg) 51 (imm i16)) 52 53 ;; An ALU operation with a register in-/out operand and a signed 32-bit 54 ;; immediate source. 55 (AluRSImm32 56 (alu_op ALUOp) 57 (rd WritableReg) 58 (ri Reg) 59 (imm i32)) 60 61 ;; An ALU operation with a register in-/out operand and an unsigned 32-bit 62 ;; immediate source. 63 (AluRUImm32 64 (alu_op ALUOp) 65 (rd WritableReg) 66 (ri Reg) 67 (imm u32)) 68 69 ;; An ALU operation with a register in-/out operand and a shifted 16-bit 70 ;; immediate source. 71 (AluRUImm16Shifted 72 (alu_op ALUOp) 73 (rd WritableReg) 74 (ri Reg) 75 (imm UImm16Shifted)) 76 77 ;; An ALU operation with a register in-/out operand and a shifted 32-bit 78 ;; immediate source. 79 (AluRUImm32Shifted 80 (alu_op ALUOp) 81 (rd WritableReg) 82 (ri Reg) 83 (imm UImm32Shifted)) 84 85 ;; A multiply operation with two register sources and a register pair destination. 86 (SMulWide 87 (rd WritableRegPair) 88 (rn Reg) 89 (rm Reg)) 90 91 ;; A multiply operation with an in/out register pair, and an extra register source. 92 ;; Only the lower half of the register pair is used as input. 93 (UMulWide 94 (rd WritableRegPair) 95 (ri Reg) 96 (rn Reg)) 97 98 ;; A divide operation with an in/out register pair, and an extra register source. 99 ;; Only the lower half of the register pair is used as input. 100 (SDivMod32 101 (rd WritableRegPair) 102 (ri Reg) 103 (rn Reg)) 104 (SDivMod64 105 (rd WritableRegPair) 106 (ri Reg) 107 (rn Reg)) 108 109 ;; A divide operation with an in/out register pair, and an extra register source. 110 (UDivMod32 111 (rd WritableRegPair) 112 (ri RegPair) 113 (rn Reg)) 114 (UDivMod64 115 (rd WritableRegPair) 116 (ri RegPair) 117 (rn Reg)) 118 119 ;; A FLOGR operation with a register source and a register pair destination. 120 (Flogr 121 (rd WritableRegPair) 122 (rn Reg)) 123 124 ;; A shift instruction with a register source, a register destination, 125 ;; and an immediate plus an optional register as shift count. 126 (ShiftRR 127 (shift_op ShiftOp) 128 (rd WritableReg) 129 (rn Reg) 130 (shift_imm u8) 131 (shift_reg Reg)) 132 133 ;; A rotate-then-<op>-selected-bits instruction with a register 134 ;; in/out-operand, another register source, and three immediates. 135 (RxSBG 136 (op RxSBGOp) 137 (rd WritableReg) 138 (ri Reg) 139 (rn Reg) 140 (start_bit u8) 141 (end_bit u8) 142 (rotate_amt i8)) 143 144 ;; The test-only version of RxSBG, which does not modify any register 145 ;; but only sets the condition code. 146 (RxSBGTest 147 (op RxSBGOp) 148 (rd Reg) 149 (rn Reg) 150 (start_bit u8) 151 (end_bit u8) 152 (rotate_amt i8)) 153 154 ;; An unary operation with a register source and a register destination. 155 (UnaryRR 156 (op UnaryOp) 157 (rd WritableReg) 158 (rn Reg)) 159 160 ;; A compare operation with two register sources. 161 (CmpRR 162 (op CmpOp) 163 (rn Reg) 164 (rm Reg)) 165 166 ;; A compare operation with a register source and a memory source. 167 (CmpRX 168 (op CmpOp) 169 (rn Reg) 170 (mem MemArg)) 171 172 ;; A compare operation with a register source and a signed 16-bit 173 ;; immediate source. 174 (CmpRSImm16 175 (op CmpOp) 176 (rn Reg) 177 (imm i16)) 178 179 ;; A compare operation with a register source and a signed 32-bit 180 ;; immediate source. 181 (CmpRSImm32 182 (op CmpOp) 183 (rn Reg) 184 (imm i32)) 185 186 ;; A compare operation with a register source and a unsigned 32-bit 187 ;; immediate source. 188 (CmpRUImm32 189 (op CmpOp) 190 (rn Reg) 191 (imm u32)) 192 193 ;; A compare-and-trap instruction with two register sources. 194 (CmpTrapRR 195 (op CmpOp) 196 (rn Reg) 197 (rm Reg) 198 (cond Cond) 199 (trap_code TrapCode)) 200 201 ;; A compare-and-trap operation with a register source and a signed 16-bit 202 ;; immediate source. 203 (CmpTrapRSImm16 204 (op CmpOp) 205 (rn Reg) 206 (imm i16) 207 (cond Cond) 208 (trap_code TrapCode)) 209 210 ;; A compare-and-trap operation with a register source and an unsigned 16-bit 211 ;; immediate source. 212 (CmpTrapRUImm16 213 (op CmpOp) 214 (rn Reg) 215 (imm u16) 216 (cond Cond) 217 (trap_code TrapCode)) 218 219 ;; An atomic read-modify-write operation with a memory in-/out operand, 220 ;; a register destination, and a register source. 221 ;; a memory source. 222 (AtomicRmw 223 (alu_op ALUOp) 224 (rd WritableReg) 225 (rn Reg) 226 (mem MemArg)) 227 228 ;; A 32-bit atomic compare-and-swap operation. 229 (AtomicCas32 230 (rd WritableReg) 231 (ri Reg) 232 (rn Reg) 233 (mem MemArg)) 234 235 ;; A 64-bit atomic compare-and-swap operation. 236 (AtomicCas64 237 (rd WritableReg) 238 (ri Reg) 239 (rn Reg) 240 (mem MemArg)) 241 242 ;; A memory fence operation. 243 (Fence) 244 245 ;; A 32-bit load. 246 (Load32 247 (rd WritableReg) 248 (mem MemArg)) 249 250 ;; An unsigned (zero-extending) 8-bit to 32-bit load. 251 (Load32ZExt8 252 (rd WritableReg) 253 (mem MemArg)) 254 255 ;; A signed (sign-extending) 8-bit to 32-bit load. 256 (Load32SExt8 257 (rd WritableReg) 258 (mem MemArg)) 259 260 ;; An unsigned (zero-extending) 16-bit to 32-bit load. 261 (Load32ZExt16 262 (rd WritableReg) 263 (mem MemArg)) 264 265 ;; A signed (sign-extending) 16-bit to 32-bit load. 266 (Load32SExt16 267 (rd WritableReg) 268 (mem MemArg)) 269 270 ;; A 64-bit load. 271 (Load64 272 (rd WritableReg) 273 (mem MemArg)) 274 275 ;; An unsigned (zero-extending) 8-bit to 64-bit load. 276 (Load64ZExt8 277 (rd WritableReg) 278 (mem MemArg)) 279 280 ;; A signed (sign-extending) 8-bit to 64-bit load. 281 (Load64SExt8 282 (rd WritableReg) 283 (mem MemArg)) 284 285 ;; An unsigned (zero-extending) 16-bit to 64-bit load. 286 (Load64ZExt16 287 (rd WritableReg) 288 (mem MemArg)) 289 290 ;; A signed (sign-extending) 16-bit to 64-bit load. 291 (Load64SExt16 292 (rd WritableReg) 293 (mem MemArg)) 294 295 ;; An unsigned (zero-extending) 32-bit to 64-bit load. 296 (Load64ZExt32 297 (rd WritableReg) 298 (mem MemArg)) 299 300 ;; A signed (sign-extending) 32-bit to 64-bit load. 301 (Load64SExt32 302 (rd WritableReg) 303 (mem MemArg)) 304 305 ;; A 16-bit byte-reversed load. 306 (LoadRev16 307 (rd WritableReg) 308 (mem MemArg)) 309 310 ;; A 32-bit byte-reversed load. 311 (LoadRev32 312 (rd WritableReg) 313 (mem MemArg)) 314 315 ;; A 64-bit byte-reversed load. 316 (LoadRev64 317 (rd WritableReg) 318 (mem MemArg)) 319 320 ;; An 8-bit store. 321 (Store8 322 (rd Reg) 323 (mem MemArg)) 324 325 ;; A 16-bit store. 326 (Store16 327 (rd Reg) 328 (mem MemArg)) 329 330 ;; A 32-bit store. 331 (Store32 332 (rd Reg) 333 (mem MemArg)) 334 335 ;; A 64-bit store. 336 (Store64 337 (rd Reg) 338 (mem MemArg)) 339 340 ;; An 8-bit store of an immediate. 341 (StoreImm8 342 (imm u8) 343 (mem MemArg)) 344 345 ;; A 16-bit store of an immediate. 346 (StoreImm16 347 (imm i16) 348 (mem MemArg)) 349 350 ;; A 32-bit store of a sign-extended 16-bit immediate. 351 (StoreImm32SExt16 352 (imm i16) 353 (mem MemArg)) 354 355 ;; A 64-bit store of a sign-extended 16-bit immediate. 356 (StoreImm64SExt16 357 (imm i16) 358 (mem MemArg)) 359 360 ;; A 16-bit byte-reversed store. 361 (StoreRev16 362 (rd Reg) 363 (mem MemArg)) 364 365 ;; A 32-bit byte-reversed store. 366 (StoreRev32 367 (rd Reg) 368 (mem MemArg)) 369 370 ;; A 64-bit byte-reversed store. 371 (StoreRev64 372 (rd Reg) 373 (mem MemArg)) 374 375 ;; A load-multiple instruction. 376 (LoadMultiple64 377 (rt WritableReg) 378 (rt2 WritableReg) 379 (mem MemArg)) 380 381 ;; A store-multiple instruction. 382 (StoreMultiple64 383 (rt Reg) 384 (rt2 Reg) 385 (mem MemArg)) 386 387 ;; A 32-bit move instruction. 388 (Mov32 389 (rd WritableReg) 390 (rm Reg)) 391 392 ;; A 64-bit move instruction. 393 (Mov64 394 (rd WritableReg) 395 (rm Reg)) 396 397 ;; Like `Mov64` but with a particular physical register source. 398 (MovPReg 399 (rd WritableReg) 400 (rm PReg)) 401 402 ;; A 32-bit move instruction with a full 32-bit immediate. 403 (Mov32Imm 404 (rd WritableReg) 405 (imm u32)) 406 407 ;; A 32-bit move instruction with a 16-bit signed immediate. 408 (Mov32SImm16 409 (rd WritableReg) 410 (imm i16)) 411 412 ;; A 64-bit move instruction with a 16-bit signed immediate. 413 (Mov64SImm16 414 (rd WritableReg) 415 (imm i16)) 416 417 ;; A 64-bit move instruction with a 32-bit signed immediate. 418 (Mov64SImm32 419 (rd WritableReg) 420 (imm i32)) 421 422 ;; A 64-bit move instruction with a shifted 16-bit immediate. 423 (Mov64UImm16Shifted 424 (rd WritableReg) 425 (imm UImm16Shifted)) 426 427 ;; A 64-bit move instruction with a shifted 32-bit immediate. 428 (Mov64UImm32Shifted 429 (rd WritableReg) 430 (imm UImm32Shifted)) 431 432 ;; A 64-bit insert instruction with a shifted 16-bit immediate. 433 (Insert64UImm16Shifted 434 (rd WritableReg) 435 (ri Reg) 436 (imm UImm16Shifted)) 437 438 ;; A 64-bit insert instruction with a shifted 32-bit immediate. 439 (Insert64UImm32Shifted 440 (rd WritableReg) 441 (ri Reg) 442 (imm UImm32Shifted)) 443 444 ;; Load 32-bit access register into GPR. 445 (LoadAR 446 (rd WritableReg) 447 (ar u8)) 448 449 ;; Insert 32-bit access register into low half of a GPR. 450 ;; (Identical operation to LoadAR, but considers rd to be use/def.) 451 (InsertAR 452 (rd WritableReg) 453 (ri Reg) 454 (ar u8)) 455 456 ;; A sign- or zero-extend operation. 457 (Extend 458 (rd WritableReg) 459 (rn Reg) 460 (signed bool) 461 (from_bits u8) 462 (to_bits u8)) 463 464 ;; A 32-bit conditional move instruction. `ri` is the value that's used if 465 ;; the conditional is true, `rm` is used otherwise. 466 (CMov32 467 (rd WritableReg) 468 (cond Cond) 469 (ri Reg) 470 (rm Reg)) 471 472 ;; A 64-bit conditional move instruction. 473 (CMov64 474 (rd WritableReg) 475 (cond Cond) 476 (ri Reg) 477 (rm Reg)) 478 479 ;; A 32-bit conditional move instruction with a 16-bit signed immediate. 480 (CMov32SImm16 481 (rd WritableReg) 482 (cond Cond) 483 (ri Reg) 484 (imm i16)) 485 486 ;; A 64-bit conditional move instruction with a 16-bit signed immediate. 487 (CMov64SImm16 488 (rd WritableReg) 489 (cond Cond) 490 (ri Reg) 491 (imm i16)) 492 493 ;; A 32-bit FPU move possibly implemented as vector instruction. 494 (FpuMove32 495 (rd WritableReg) 496 (rn Reg)) 497 498 ;; A 64-bit FPU move possibly implemented as vector instruction. 499 (FpuMove64 500 (rd WritableReg) 501 (rn Reg)) 502 503 ;; A 32-bit conditional move FPU instruction, possibly as vector instruction. 504 (FpuCMov32 505 (rd WritableReg) 506 (cond Cond) 507 (ri Reg) 508 (rm Reg)) 509 510 ;; A 64-bit conditional move FPU instruction, possibly as vector instruction. 511 (FpuCMov64 512 (rd WritableReg) 513 (cond Cond) 514 (ri Reg) 515 (rm Reg)) 516 517 ;; 1-op FPU instruction implemented as vector instruction with the W bit. 518 (FpuRR 519 (fpu_op FPUOp1) 520 (rd WritableReg) 521 (rn Reg)) 522 523 ;; 2-op FPU instruction implemented as vector instruction with the W bit. 524 (FpuRRR 525 (fpu_op FPUOp2) 526 (rd WritableReg) 527 (rn Reg) 528 (rm Reg)) 529 530 ;; 3-op FPU instruction implemented as vector instruction with the W bit. 531 (FpuRRRR 532 (fpu_op FPUOp3) 533 (rd WritableReg) 534 (rn Reg) 535 (rm Reg) 536 (ra Reg)) 537 538 ;; 1-op FPU instruction with rounding mode. 539 (FpuRound 540 (op FpuRoundOp) 541 (mode FpuRoundMode) 542 (rd WritableReg) 543 (rn Reg)) 544 545 ;; FPU comparison, single-precision (32 bit). 546 (FpuCmp32 547 (rn Reg) 548 (rm Reg)) 549 550 ;; FPU comparison, double-precision (64 bit). 551 (FpuCmp64 552 (rn Reg) 553 (rm Reg)) 554 555 ;; FPU comparison, extended-precision (128 bit). 556 (FpuCmp128 557 (rn Reg) 558 (rm Reg)) 559 560 ;; FPU integer to extended-precision conversion using FP reg pair. 561 (FpuConv128FromInt 562 (op FpuConv128Op) 563 (mode FpuRoundMode) 564 (rd WritableRegPair) 565 (rn Reg)) 566 567 ;; FPU extended-precision to integer conversion using FP reg pair. 568 (FpuConv128ToInt 569 (op FpuConv128Op) 570 (mode FpuRoundMode) 571 (rd WritableReg) 572 (rn RegPair)) 573 574 ;; A binary vector operation with two vector register sources. 575 (VecRRR 576 (op VecBinaryOp) 577 (rd WritableReg) 578 (rn Reg) 579 (rm Reg)) 580 581 ;; A unary vector operation with a vector register source. 582 (VecRR 583 (op VecUnaryOp) 584 (rd WritableReg) 585 (rn Reg)) 586 587 ;; Vector shift instruction with a register source, a register destination, 588 ;; and an immediate plus an optional register as shift count. 589 (VecShiftRR 590 (shift_op VecShiftOp) 591 (rd WritableReg) 592 (rn Reg) 593 (shift_imm u8) 594 (shift_reg Reg)) 595 596 ;; Vector select instruction. 597 (VecSelect 598 (rd WritableReg) 599 (rn Reg) 600 (rm Reg) 601 (ra Reg)) 602 603 ;; Vector merge instruction. 604 (VecBlend 605 (rd WritableReg) 606 (rn Reg) 607 (rm Reg) 608 (ra Reg)) 609 610 ;; Vector permute instruction. 611 (VecPermute 612 (rd WritableReg) 613 (rn Reg) 614 (rm Reg) 615 (ra Reg)) 616 617 ;; Vector evaluate instruction. 618 (VecEvaluate 619 (imm u8) 620 (rd WritableReg) 621 (rn Reg) 622 (rm Reg) 623 (ra Reg)) 624 625 ;; Vector permute doubleword immediate instruction. 626 (VecPermuteDWImm 627 (rd WritableReg) 628 (rn Reg) 629 (rm Reg) 630 (idx1 u8) 631 (idx2 u8)) 632 633 ;; Vector integer comparison with two register sources and a register 634 ;; destination. 635 (VecIntCmp 636 (op VecIntCmpOp) 637 (rd WritableReg) 638 (rn Reg) 639 (rm Reg)) 640 641 ;; Same, but also set the condition code. 642 (VecIntCmpS 643 (op VecIntCmpOp) 644 (rd WritableReg) 645 (rn Reg) 646 (rm Reg)) 647 648 ;; Vector floating-point comparison with two register sources and a register 649 ;; destination. 650 (VecFloatCmp 651 (op VecFloatCmpOp) 652 (rd WritableReg) 653 (rn Reg) 654 (rm Reg)) 655 656 ;; Same, but also set the condition code. 657 (VecFloatCmpS 658 (op VecFloatCmpOp) 659 (rd WritableReg) 660 (rn Reg) 661 (rm Reg)) 662 663 ;; Vector integer element comparison with two registers sources, 664 ;; setting the condition code. 665 (VecIntEltCmp 666 (op VecIntEltCmpOp) 667 (rn Reg) 668 (rm Reg)) 669 670 ;; Synthetic instruction to compare signed 128-bit values. 671 ;; Sets CC 1 if rn > rm, sets a different CC otherwise. 672 (VecInt128SCmpHi 673 (tmp WritableReg) 674 (rn Reg) 675 (rm Reg)) 676 677 ;; Synthetic instruction to compare unsigned 128-bit values. 678 ;; Sets CC 1 if rn > rm, sets a different CC otherwise. 679 (VecInt128UCmpHi 680 (tmp WritableReg) 681 (rn Reg) 682 (rm Reg)) 683 684 ;; 128-bit vector load instruction. 685 (VecLoad 686 (rd WritableReg) 687 (mem MemArg)) 688 689 ;; 128-bit byte-reversed vector load instruction. 690 (VecLoadRev 691 (rd WritableReg) 692 (mem MemArg)) 693 694 ;; 8x16-bit byte-reversed vector load instruction. 695 (VecLoadByte16Rev 696 (rd WritableReg) 697 (mem MemArg)) 698 699 ;; 4x32-bit byte-reversed vector load instruction. 700 (VecLoadByte32Rev 701 (rd WritableReg) 702 (mem MemArg)) 703 704 ;; 2x64-bit byte-reversed vector load instruction. 705 (VecLoadByte64Rev 706 (rd WritableReg) 707 (mem MemArg)) 708 709 ;; 8x16-bit element-reversed vector load instruction. 710 (VecLoadElt16Rev 711 (rd WritableReg) 712 (mem MemArg)) 713 714 ;; 4x32-bit element-reversed vector load instruction. 715 (VecLoadElt32Rev 716 (rd WritableReg) 717 (mem MemArg)) 718 719 ;; 2x64-bit element-reversed vector load instruction. 720 (VecLoadElt64Rev 721 (rd WritableReg) 722 (mem MemArg)) 723 724 ;; 128-bit vector store instruction. 725 (VecStore 726 (rd Reg) 727 (mem MemArg)) 728 729 ;; 128-bit byte-reversed vector store instruction. 730 (VecStoreRev 731 (rd Reg) 732 (mem MemArg)) 733 734 ;; 8x16-bit byte-reversed vector store instruction. 735 (VecStoreByte16Rev 736 (rd Reg) 737 (mem MemArg)) 738 739 ;; 4x32-bit byte-reversed vector store instruction. 740 (VecStoreByte32Rev 741 (rd Reg) 742 (mem MemArg)) 743 744 ;; 2x64-bit byte-reversed vector store instruction. 745 (VecStoreByte64Rev 746 (rd Reg) 747 (mem MemArg)) 748 749 ;; 8x16-bit element-reversed vector store instruction. 750 (VecStoreElt16Rev 751 (rd Reg) 752 (mem MemArg)) 753 754 ;; 4x32-bit element-reversed vector store instruction. 755 (VecStoreElt32Rev 756 (rd Reg) 757 (mem MemArg)) 758 759 ;; 2x64-bit element-reversed vector store instruction. 760 (VecStoreElt64Rev 761 (rd Reg) 762 (mem MemArg)) 763 764 ;; 128-bit vector load replicated element instruction. 765 (VecLoadReplicate 766 (size u32) 767 (rd WritableReg) 768 (mem MemArg)) 769 770 ;; 128-bit byte-reversed vector load replicated element instruction. 771 (VecLoadReplicateRev 772 (size u32) 773 (rd WritableReg) 774 (mem MemArg)) 775 776 ;; Vector move instruction. 777 (VecMov 778 (rd WritableReg) 779 (rn Reg)) 780 781 ;; Conditional vector move instruction. 782 (VecCMov 783 (rd WritableReg) 784 (cond Cond) 785 (ri Reg) 786 (rm Reg)) 787 788 ;; A 128-bit move instruction from two GPRs to a VR. 789 (MovToVec128 790 (rd WritableReg) 791 (rn Reg) 792 (rm Reg)) 793 794 ;; Load vector immediate generated via byte mask. 795 (VecImmByteMask 796 (rd WritableReg) 797 (mask u16)) 798 799 ;; Load vector replicated contiguous bit mask. 800 (VecImmBitMask 801 (size u32) 802 (rd WritableReg) 803 (start_bit u8) 804 (end_bit u8)) 805 806 ;; Load vector replicated immediate. 807 (VecImmReplicate 808 (size u32) 809 (rd WritableReg) 810 (imm i16)) 811 812 ;; Vector lane insertion with an in/out VR, a memory source, 813 ;; and an immediate as lane index. 814 (VecLoadLane 815 (size u32) 816 (rd WritableReg) 817 (ri Reg) 818 (mem MemArg) 819 (lane_imm u8)) 820 821 ;; Same as VecLoadLane, but allow undefined input VR. 822 (VecLoadLaneUndef 823 (size u32) 824 (rd WritableReg) 825 (mem MemArg) 826 (lane_imm u8)) 827 828 ;; Byte-reversed vector lane insertion with an in/out VR, a memory source, 829 ;; and an immediate as lane index. 830 (VecLoadLaneRev 831 (size u32) 832 (rd WritableReg) 833 (ri Reg) 834 (mem MemArg) 835 (lane_imm u8)) 836 837 ;; Same as VecLoadLaneRev, but allow undefined input VR. 838 (VecLoadLaneRevUndef 839 (size u32) 840 (rd WritableReg) 841 (mem MemArg) 842 (lane_imm u8)) 843 844 ;; Vector lane extraction with a memory destination, a VR source, 845 ;; and an immediate as lane index. 846 (VecStoreLane 847 (size u32) 848 (rd Reg) 849 (mem MemArg) 850 (lane_imm u8)) 851 852 ;; Byte-reversed vector lane extraction with a memory destination, a VR source, 853 ;; and an immediate as lane index. 854 (VecStoreLaneRev 855 (size u32) 856 (rd Reg) 857 (mem MemArg) 858 (lane_imm u8)) 859 860 ;; Vector lane insertion with an in/out VR, a GPR source, 861 ;; and an immediate plus an optional register as lane index. 862 (VecInsertLane 863 (size u32) 864 (rd WritableReg) 865 (ri Reg) 866 (rn Reg) 867 (lane_imm u8) 868 (lane_reg Reg)) 869 870 ;; Same as VecInsertLane, but allow undefined input VR. 871 (VecInsertLaneUndef 872 (size u32) 873 (rd WritableReg) 874 (rn Reg) 875 (lane_imm u8) 876 (lane_reg Reg)) 877 878 ;; Vector lane extraction with a VR source, a GPR destination, 879 ;; and an immediate plus an optional register as lane index. 880 (VecExtractLane 881 (size u32) 882 (rd WritableReg) 883 (rn Reg) 884 (lane_imm u8) 885 (lane_reg Reg)) 886 887 ;; Vector lane insertion with an in/out VR, an immediate source, 888 ;; and an immediate as lane index. 889 (VecInsertLaneImm 890 (size u32) 891 (rd WritableReg) 892 (ri Reg) 893 (imm i16) 894 (lane_imm u8)) 895 896 ;; Same as VecInsertLaneImm, but allow undefined input VR. 897 (VecInsertLaneImmUndef 898 (size u32) 899 (rd WritableReg) 900 (imm i16) 901 (lane_imm u8)) 902 903 ;; Vector lane replication with a VR source, a VR destination, 904 ;; and an immediate as lane index. 905 (VecReplicateLane 906 (size u32) 907 (rd WritableReg) 908 (rn Reg) 909 (lane_imm u8)) 910 911 ;; Synthetic instruction to reverse vector elements in-register. 912 (VecEltRev 913 (lane_count u32) 914 (rd WritableReg) 915 (rn Reg)) 916 917 ;; Allocate stack space for outgoing tail-call arguments. 918 (AllocateArgs 919 (size u32)) 920 921 ;; A machine call instruction (direct or indirect). 922 (Call 923 (link WritableReg) 924 (info BoxCallInfo)) 925 926 ;; A machine tail call instruction (direct or indirect). 927 (ReturnCall 928 (info BoxReturnCallInfo)) 929 930 ;; A pseudo-instruction that captures register arguments in vregs. 931 (Args 932 (args VecArgPair)) 933 934 ;; A pseudo-instruction that moves vregs to return registers. 935 (Rets 936 (rets VecRetPair)) 937 938 ;; ---- branches (exactly one must appear at end of BB) ---- 939 940 ;; A machine return instruction. 941 (Ret 942 (link Reg)) 943 944 ;; An unconditional branch. 945 (Jump 946 (dest MachLabel)) 947 948 ;; A conditional branch. Contains two targets; at emission time, both are emitted, but 949 ;; the MachBuffer knows to truncate the trailing branch if fallthrough. We optimize the 950 ;; choice of taken/not_taken (inverting the branch polarity as needed) based on the 951 ;; fallthrough at the time of lowering. 952 (CondBr 953 (taken MachLabel) 954 (not_taken MachLabel) 955 (cond Cond)) 956 957 ;; A conditional trap execute a `Trap` if the condition is true. This is 958 ;; one VCode instruction because it uses embedded control flow; it is 959 ;; logically a single-in, single-out region, but needs to appear as one 960 ;; unit to the register allocator. 961 ;; 962 ;; The `Cond` gives the conditional-branch condition that will 963 ;; *execute* the embedded `Trap`. (In the emitted code, we use the inverse 964 ;; of this condition in a branch that skips the trap instruction.) 965 (TrapIf 966 (cond Cond) 967 (trap_code TrapCode)) 968 969 ;; An indirect branch through a register, augmented with set of all 970 ;; possible successors. 971 (IndirectBr 972 (rn Reg) 973 (targets VecMachLabel)) 974 975 ;; A "debugtrap" instruction, used for e.g. traps and debug breakpoints. 976 (Debugtrap) 977 978 ;; An instruction guaranteed to always be undefined and to trigger an illegal instruction at 979 ;; runtime. 980 (Trap 981 (trap_code TrapCode)) 982 983 ;; Jump-table sequence, as one compound instruction (see note in lower.rs 984 ;; for rationale). 985 (JTSequence 986 ;; The index into the list of targets. 987 (ridx Reg) 988 ;; The default target. 989 (default MachLabel) 990 ;; The condition for taking the default target, based on flags 991 ;; when this instruction executes. 992 (default_cond Cond) 993 ;; All other targets. 994 (targets BoxVecMachLabel)) 995 996 ;; Stack probe loop sequence, as one compound instruction. 997 (StackProbeLoop 998 (probe_count WritableReg) 999 (guard_size i16)) 1000 1001 ;; Load an inline symbol reference with relocation. 1002 (LoadSymbolReloc 1003 (rd WritableReg) 1004 (symbol_reloc BoxSymbolReloc)) 1005 1006 ;; Load address referenced by `mem` into `rd`. 1007 (LoadAddr 1008 (rd WritableReg) 1009 (mem MemArg)) 1010 1011 ;; Meta-instruction to emit a loop around a sequence of instructions. 1012 ;; This control flow is not visible to the compiler core, in particular 1013 ;; the register allocator. Therefore, instructions in the loop may not 1014 ;; write to any virtual register, so any writes must use reserved hard 1015 ;; registers (e.g. %r0, %r1). *Reading* virtual registers is OK. 1016 (Loop 1017 (body VecMInst) 1018 (cond Cond)) 1019 1020 ;; Conditional branch breaking out of a loop emitted via Loop. 1021 (CondBreak 1022 (cond Cond)) 1023 1024 ;; Pseudoinstruction to keep a value alive. 1025 (DummyUse 1026 (reg Reg)) 1027 1028 ;; An unwind pseudoinstruction describing the state of the 1029 ;; machine at this program point. 1030 (Unwind 1031 (inst UnwindInst)) 1032 1033 ;; Pseudo-instruction used for `tls_value` to call the libcall of the same 1034 ;; name. 1035 (ElfTlsGetOffset 1036 (tls_offset WritableReg) 1037 (got Reg) 1038 (got_offset Reg) 1039 (symbol BoxSymbolReloc)) 1040 1041 ;; A pseudoinstruction that loads the address of a label. 1042 (LabelAddress (dst WritableReg) 1043 (label MachLabel)) 1044 1045 ;; A pseudoinstruction that serves as a sequence point. 1046 (SequencePoint) 1047)) 1048 1049;; Primitive types used in instruction formats. 1050 1051(type CallInstDest (primitive CallInstDest)) 1052(type BoxCallInfo (primitive BoxCallInfo)) 1053(type BoxReturnCallInfo (primitive BoxReturnCallInfo)) 1054(type BoxJTSequenceInfo (primitive BoxJTSequenceInfo)) 1055(type VecMachLabel extern (enum)) 1056 1057(decl call_inst_dest_direct (ExternalName) CallInstDest) 1058(extern constructor call_inst_dest_direct call_inst_dest_direct) 1059(convert ExternalName CallInstDest call_inst_dest_direct) 1060 1061(decl call_inst_dest_indirect (Reg) CallInstDest) 1062(extern constructor call_inst_dest_indirect call_inst_dest_indirect) 1063(convert Reg CallInstDest call_inst_dest_indirect) 1064 1065;; A symbol reference carrying relocation information. 1066(type SymbolReloc 1067 (enum 1068 ;; Absolute symbol reference (with optional offset). 1069 (Absolute 1070 (name ExternalName) 1071 (offset i64)) 1072 ;; Reference to a TLS symbol in general-dynamic mode. 1073 (TlsGd 1074 (name ExternalName)))) 1075 1076;; Boxed version of SymbolReloc to save space. 1077(type BoxSymbolReloc (primitive BoxSymbolReloc)) 1078(decl box_symbol_reloc (SymbolReloc) BoxSymbolReloc) 1079(extern constructor box_symbol_reloc box_symbol_reloc) 1080(convert SymbolReloc BoxSymbolReloc box_symbol_reloc) 1081 1082;; An ALU operation. 1083(type ALUOp 1084 (enum 1085 (Add32) 1086 (Add32Ext16) 1087 (Add64) 1088 (Add64Ext16) 1089 (Add64Ext32) 1090 (AddLogical32) 1091 (AddLogical64) 1092 (AddLogical64Ext32) 1093 (Sub32) 1094 (Sub32Ext16) 1095 (Sub64) 1096 (Sub64Ext16) 1097 (Sub64Ext32) 1098 (SubLogical32) 1099 (SubLogical64) 1100 (SubLogical64Ext32) 1101 (Mul32) 1102 (Mul32Ext16) 1103 (Mul64) 1104 (Mul64Ext16) 1105 (Mul64Ext32) 1106 (And32) 1107 (And64) 1108 (Orr32) 1109 (Orr64) 1110 (Xor32) 1111 (Xor64) 1112 ;; NAND 1113 (NotAnd32) 1114 (NotAnd64) 1115 ;; NOR 1116 (NotOrr32) 1117 (NotOrr64) 1118 ;; XNOR 1119 (NotXor32) 1120 (NotXor64) 1121 ;; And with complement 1122 (AndNot32) 1123 (AndNot64) 1124 ;; Or with complement 1125 (OrrNot32) 1126 (OrrNot64) 1127)) 1128 1129;; A unary operation. 1130(type UnaryOp 1131 (enum 1132 (Abs32) 1133 (Abs64) 1134 (Abs64Ext32) 1135 (Neg32) 1136 (Neg64) 1137 (Neg64Ext32) 1138 (PopcntByte) 1139 (PopcntReg) 1140 (BSwap32) 1141 (BSwap64) 1142 (Clz64) 1143 (Ctz64) 1144)) 1145 1146;; A shift operation. 1147(type ShiftOp 1148 (enum 1149 (RotL32) 1150 (RotL64) 1151 (LShL32) 1152 (LShL64) 1153 (LShR32) 1154 (LShR64) 1155 (AShR32) 1156 (AShR64) 1157)) 1158 1159;; A rotate-then-<op>-selected-bits operation. 1160(type RxSBGOp 1161 (enum 1162 (Insert) 1163 (And) 1164 (Or) 1165 (Xor) 1166)) 1167 1168;; An integer comparison operation. 1169(type CmpOp 1170 (enum 1171 (CmpS32) 1172 (CmpS32Ext16) 1173 (CmpS64) 1174 (CmpS64Ext16) 1175 (CmpS64Ext32) 1176 (CmpL32) 1177 (CmpL32Ext16) 1178 (CmpL64) 1179 (CmpL64Ext16) 1180 (CmpL64Ext32) 1181)) 1182 1183;; A binary vector operation. 1184(type VecBinaryOp 1185 (enum 1186 ;; Addition and subtraction 1187 (Add8x16) 1188 (Add16x8) 1189 (Add32x4) 1190 (Add64x2) 1191 (Add128) 1192 (Sub8x16) 1193 (Sub16x8) 1194 (Sub32x4) 1195 (Sub64x2) 1196 (Sub128) 1197 ;; Multiplication 1198 (Mul8x16) 1199 (Mul16x8) 1200 (Mul32x4) 1201 (Mul64x2) 1202 (Mul128) 1203 (UMulHi8x16) 1204 (UMulHi16x8) 1205 (UMulHi32x4) 1206 (UMulHi64x2) 1207 (UMulHi128) 1208 (SMulHi8x16) 1209 (SMulHi16x8) 1210 (SMulHi32x4) 1211 (SMulHi64x2) 1212 (SMulHi128) 1213 (UMulEven8x16) 1214 (UMulEven16x8) 1215 (UMulEven32x4) 1216 (UMulEven64x2) 1217 (SMulEven8x16) 1218 (SMulEven16x8) 1219 (SMulEven32x4) 1220 (SMulEven64x2) 1221 (UMulOdd8x16) 1222 (UMulOdd16x8) 1223 (UMulOdd32x4) 1224 (UMulOdd64x2) 1225 (SMulOdd8x16) 1226 (SMulOdd16x8) 1227 (SMulOdd32x4) 1228 (SMulOdd64x2) 1229 ;; Division and remainder 1230 (UDiv32x4) 1231 (UDiv64x2) 1232 (UDiv128) 1233 (URem32x4) 1234 (URem64x2) 1235 (URem128) 1236 (SDiv32x4) 1237 (SDiv64x2) 1238 (SDiv128) 1239 (SRem32x4) 1240 (SRem64x2) 1241 (SRem128) 1242 ;; Minimum, maximum, and average 1243 (UMax8x16) 1244 (UMax16x8) 1245 (UMax32x4) 1246 (UMax64x2) 1247 (UMax128) 1248 (SMax8x16) 1249 (SMax16x8) 1250 (SMax32x4) 1251 (SMax64x2) 1252 (SMax128) 1253 (UMin8x16) 1254 (UMin16x8) 1255 (UMin32x4) 1256 (UMin64x2) 1257 (UMin128) 1258 (SMin8x16) 1259 (SMin16x8) 1260 (SMin32x4) 1261 (SMin64x2) 1262 (SMin128) 1263 (UAvg8x16) 1264 (UAvg16x8) 1265 (UAvg32x4) 1266 (UAvg64x2) 1267 (UAvg128) 1268 (SAvg8x16) 1269 (SAvg16x8) 1270 (SAvg32x4) 1271 (SAvg64x2) 1272 (SAvg128) 1273 ;; Bitwise operations 1274 (And128) 1275 (Orr128) 1276 (Xor128) 1277 (NotAnd128) 1278 (NotOrr128) 1279 (NotXor128) 1280 (AndNot128) 1281 (OrrNot128) 1282 ;; Bit permute 1283 (BitPermute128) 1284 ;; Full vector shift operations 1285 (LShLByByte128) 1286 (LShRByByte128) 1287 (AShRByByte128) 1288 (LShLByBit128) 1289 (LShRByBit128) 1290 (AShRByBit128) 1291 ;; Pack 1292 (Pack16x8) 1293 (Pack32x4) 1294 (Pack64x2) 1295 ;; Pack saturate (unsigned) 1296 (PackUSat16x8) 1297 (PackUSat32x4) 1298 (PackUSat64x2) 1299 ;; Pack saturate (signed) 1300 (PackSSat16x8) 1301 (PackSSat32x4) 1302 (PackSSat64x2) 1303 ;; Merge 1304 (MergeLow8x16) 1305 (MergeLow16x8) 1306 (MergeLow32x4) 1307 (MergeLow64x2) 1308 (MergeHigh8x16) 1309 (MergeHigh16x8) 1310 (MergeHigh32x4) 1311 (MergeHigh64x2) 1312)) 1313 1314;; A vector unary operation. 1315(type VecUnaryOp 1316 (enum 1317 ;; Sign operations 1318 (Abs8x16) 1319 (Abs16x8) 1320 (Abs32x4) 1321 (Abs64x2) 1322 (Abs128) 1323 (Neg8x16) 1324 (Neg16x8) 1325 (Neg32x4) 1326 (Neg64x2) 1327 (Neg128) 1328 ;; Population count 1329 (Popcnt8x16) 1330 (Popcnt16x8) 1331 (Popcnt32x4) 1332 (Popcnt64x2) 1333 ;; Count leading/trailing zeros 1334 (Clz8x16) 1335 (Clz16x8) 1336 (Clz32x4) 1337 (Clz64x2) 1338 (Clz128) 1339 (Ctz8x16) 1340 (Ctz16x8) 1341 (Ctz32x4) 1342 (Ctz64x2) 1343 (Ctz128) 1344 ;; Unpack 1345 (UnpackULow8x16) 1346 (UnpackULow16x8) 1347 (UnpackULow32x4) 1348 (UnpackULow64x2) 1349 (UnpackUHigh8x16) 1350 (UnpackUHigh16x8) 1351 (UnpackUHigh32x4) 1352 (UnpackUHigh64x2) 1353 (UnpackSLow8x16) 1354 (UnpackSLow16x8) 1355 (UnpackSLow32x4) 1356 (UnpackSLow64x2) 1357 (UnpackSHigh8x16) 1358 (UnpackSHigh16x8) 1359 (UnpackSHigh32x4) 1360 (UnpackSHigh64x2) 1361)) 1362 1363;; A vector shift operation. 1364(type VecShiftOp 1365 (enum 1366 (RotL8x16) 1367 (RotL16x8) 1368 (RotL32x4) 1369 (RotL64x2) 1370 (LShL8x16) 1371 (LShL16x8) 1372 (LShL32x4) 1373 (LShL64x2) 1374 (LShR8x16) 1375 (LShR16x8) 1376 (LShR32x4) 1377 (LShR64x2) 1378 (AShR8x16) 1379 (AShR16x8) 1380 (AShR32x4) 1381 (AShR64x2) 1382)) 1383 1384;; An integer vector comparison operation. 1385(type VecIntCmpOp 1386 (enum 1387 (CmpEq8x16) 1388 (CmpEq16x8) 1389 (CmpEq32x4) 1390 (CmpEq64x2) 1391 (CmpEq128) 1392 (SCmpHi8x16) 1393 (SCmpHi16x8) 1394 (SCmpHi32x4) 1395 (SCmpHi64x2) 1396 (SCmpHi128) 1397 (UCmpHi8x16) 1398 (UCmpHi16x8) 1399 (UCmpHi32x4) 1400 (UCmpHi64x2) 1401 (UCmpHi128) 1402)) 1403 1404;; An integer vector element comparison operation. 1405(type VecIntEltCmpOp 1406 (enum 1407 (SCmp128) 1408 (UCmp128) 1409)); 1410 1411;; A floating-point vector comparison operation. 1412(type VecFloatCmpOp 1413 (enum 1414 (CmpEq32x4) 1415 (CmpEq64x2) 1416 (CmpHi32x4) 1417 (CmpHi64x2) 1418 (CmpHiEq32x4) 1419 (CmpHiEq64x2) 1420)) 1421 1422;; A floating-point unit (FPU) operation with one arg. 1423(type FPUOp1 1424 (enum 1425 (Abs32) 1426 (Abs64) 1427 (Abs128) 1428 (Abs32x4) 1429 (Abs64x2) 1430 (Neg32) 1431 (Neg64) 1432 (Neg128) 1433 (Neg32x4) 1434 (Neg64x2) 1435 (NegAbs32) 1436 (NegAbs64) 1437 (NegAbs128) 1438 (NegAbs32x4) 1439 (NegAbs64x2) 1440 (Sqrt32) 1441 (Sqrt64) 1442 (Sqrt128) 1443 (Sqrt32x4) 1444 (Sqrt64x2) 1445 (Cvt32To64) 1446 (Cvt32x4To64x2) 1447 (Cvt64To128) 1448)) 1449 1450;; A floating-point unit (FPU) operation with two args. 1451(type FPUOp2 1452 (enum 1453 (Add32) 1454 (Add64) 1455 (Add128) 1456 (Add32x4) 1457 (Add64x2) 1458 (Sub32) 1459 (Sub64) 1460 (Sub128) 1461 (Sub32x4) 1462 (Sub64x2) 1463 (Mul32) 1464 (Mul64) 1465 (Mul128) 1466 (Mul32x4) 1467 (Mul64x2) 1468 (Div32) 1469 (Div64) 1470 (Div128) 1471 (Div32x4) 1472 (Div64x2) 1473 (Max32) 1474 (Max64) 1475 (Max128) 1476 (Max32x4) 1477 (Max64x2) 1478 (Min32) 1479 (Min64) 1480 (Min128) 1481 (Min32x4) 1482 (Min64x2) 1483 (MaxPseudo32) 1484 (MaxPseudo64) 1485 (MaxPseudo128) 1486 (MaxPseudo32x4) 1487 (MaxPseudo64x2) 1488 (MinPseudo32) 1489 (MinPseudo64) 1490 (MinPseudo128) 1491 (MinPseudo32x4) 1492 (MinPseudo64x2) 1493)) 1494 1495;; A floating-point unit (FPU) operation with three args. 1496(type FPUOp3 1497 (enum 1498 (MAdd32) 1499 (MAdd64) 1500 (MAdd128) 1501 (MAdd32x4) 1502 (MAdd64x2) 1503 (MSub32) 1504 (MSub64) 1505 (MSub128) 1506 (MSub32x4) 1507 (MSub64x2) 1508)) 1509 1510;; A floating-point unit (FPU) operation with one arg, and rounding mode. 1511(type FpuRoundOp 1512 (enum 1513 (Cvt64To32) 1514 (Cvt64x2To32x4) 1515 (Cvt128To64) 1516 (Round32) 1517 (Round64) 1518 (Round128) 1519 (Round32x4) 1520 (Round64x2) 1521 (ToSInt32) 1522 (ToSInt64) 1523 (ToUInt32) 1524 (ToUInt64) 1525 (ToSInt32x4) 1526 (ToSInt64x2) 1527 (ToUInt32x4) 1528 (ToUInt64x2) 1529 (FromSInt32) 1530 (FromSInt64) 1531 (FromUInt32) 1532 (FromUInt64) 1533 (FromSInt32x4) 1534 (FromSInt64x2) 1535 (FromUInt32x4) 1536 (FromUInt64x2) 1537)) 1538 1539;; An extended-precision vs. integer conversion operation. 1540(type FpuConv128Op 1541 (enum 1542 (SInt32) 1543 (UInt32) 1544 (SInt64) 1545 (UInt64) 1546)) 1547 1548;; Rounding modes for floating-point ops. 1549(type FpuRoundMode 1550 (enum 1551 (Current) 1552 (ToNearest) 1553 (ShorterPrecision) 1554 (ToNearestTiesToEven) 1555 (ToZero) 1556 (ToPosInfinity) 1557 (ToNegInfinity) 1558)) 1559 1560 1561;; Helpers for querying enabled ISA extensions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1562 1563(decl mie3_enabled () Type) 1564(extern extractor mie3_enabled mie3_enabled) 1565(decl mie3_disabled () Type) 1566(extern extractor mie3_disabled mie3_disabled) 1567(decl mie4_enabled () Type) 1568(extern extractor mie4_enabled mie4_enabled) 1569(decl mie4_disabled () Type) 1570(extern extractor mie4_disabled mie4_disabled) 1571 1572(decl vxrs_ext2_enabled () Type) 1573(extern extractor vxrs_ext2_enabled vxrs_ext2_enabled) 1574(decl vxrs_ext2_disabled () Type) 1575(extern extractor vxrs_ext2_disabled vxrs_ext2_disabled) 1576(decl vxrs_ext3_enabled () Type) 1577(extern extractor vxrs_ext3_enabled vxrs_ext3_enabled) 1578(decl vxrs_ext3_disabled () Type) 1579(extern extractor vxrs_ext3_disabled vxrs_ext3_disabled) 1580 1581;; Helpers for SIMD lane number operations ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1582 1583;; There are two ways to map vector types onto the SIMD vector registers 1584;; supported by the ISA, differing by the way lanes are numbered. In 1585;; little-endian lane order, lane 0 of a multi-lane vector value resides 1586;; in the least-significant parts of a vector register (when interpreted 1587;; as holding a single $I128 value); in big-endian lane order, lane 0 1588;; instead resides in the most-significant parts of the register. 1589;; 1590;; As long as used consistently, output of cranelift may use either lane 1591;; order method to implement CLIF semantics. However, depending on the 1592;; particular use case, one or the other order will lead to more efficient 1593;; code. Therefore this back end supports both code generation options. 1594;; 1595;; Note that the ISA instructions use immediate lane number according 1596;; to big-endian lane order; so when using little-endian lane order, 1597;; immediate lane numbers have to be translated. 1598(type LaneOrder 1599 (enum 1600 (LittleEndian) 1601 (BigEndian))) 1602 1603;; Return the lane order to be used when compiling the current function. 1604;; This will be a property of the function ABI. Functions using the 1605;; the Wasmtime ABI will use little-endian lane order, functions using 1606;; other ABIs will big-endian lane order. 1607(decl pure lane_order () LaneOrder) 1608(extern constructor lane_order lane_order) 1609 1610;; Check whether two lane order values are equal. 1611(decl pure lane_order_equal (LaneOrder LaneOrder) bool) 1612(rule (lane_order_equal (LaneOrder.LittleEndian) (LaneOrder.LittleEndian)) true) 1613(rule (lane_order_equal (LaneOrder.LittleEndian) (LaneOrder.BigEndian)) false) 1614(rule (lane_order_equal (LaneOrder.BigEndian) (LaneOrder.LittleEndian)) false) 1615(rule (lane_order_equal (LaneOrder.BigEndian) (LaneOrder.BigEndian)) true) 1616 1617;; Return lane order matching memory byte order. 1618(decl pure lane_order_from_memflags (MemFlags) LaneOrder) 1619(rule 0 (lane_order_from_memflags (littleendian)) (LaneOrder.LittleEndian)) 1620(rule 1 (lane_order_from_memflags (bigendian)) (LaneOrder.BigEndian)) 1621 1622;; Convert a CLIF immediate lane index value to big-endian lane order. 1623(decl be_lane_idx (Type u8) u8) 1624(extern constructor be_lane_idx be_lane_idx) 1625 1626;; Convert a CLIF immediate vector constant to big-endian lane order. 1627(decl be_vec_const (Type u128) u128) 1628(extern constructor be_vec_const be_vec_const) 1629 1630 1631;; Helpers for register numbers and types ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1632 1633;; Hard-coded registers. 1634(decl writable_gpr (u8) WritableReg) 1635(extern constructor writable_gpr writable_gpr) 1636 1637;; The zero register. 1638(decl zero_reg () Reg) 1639(extern constructor zero_reg zero_reg) 1640 1641;; Types that can be operated on using 32-bit GPR instructions 1642(decl gpr32_ty (Type) Type) 1643(extern extractor gpr32_ty gpr32_ty) 1644 1645;; Types that can be operated on using 64-bit GPR instructions 1646(decl gpr64_ty (Type) Type) 1647(extern extractor gpr64_ty gpr64_ty) 1648 1649;; Types that can be operated on using 128-bit vector instructions 1650(decl vr128_ty (Type) Type) 1651(extern extractor vr128_ty vr128_ty) 1652 1653 1654;; Helpers for various immediate constants ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1655 1656;; Special integer types and their constructors 1657 1658(type UImm32Shifted (primitive UImm32Shifted)) 1659(decl uimm32shifted (u32 u8) UImm32Shifted) 1660(extern constructor uimm32shifted uimm32shifted) 1661 1662(type UImm16Shifted (primitive UImm16Shifted)) 1663(decl uimm16shifted (u16 u8) UImm16Shifted) 1664(extern constructor uimm16shifted uimm16shifted) 1665 1666;; Detect specific integer values 1667 1668(decl pure partial i64_nonequal (i64 i64) i64) 1669(extern constructor i64_nonequal i64_nonequal) 1670 1671(decl pure partial i64_not_neg1 (i64) i64) 1672(rule (i64_not_neg1 x) 1673 (if (i64_nonequal x -1)) 1674 x) 1675 1676;; Construct and extract immediate vector constants. 1677 1678(decl u64_pair (u64 u64) u128) 1679(extern constructor u64_pair u64_pair_concat) 1680(extern extractor infallible u64_pair u64_pair_split) 1681 1682(decl u32_pair (u32 u32) u64) 1683(extern constructor u32_pair u32_pair_concat) 1684(extern extractor infallible u32_pair u32_pair_split) 1685 1686(decl u16_pair (u16 u16) u32) 1687(extern constructor u16_pair u16_pair_concat) 1688(extern extractor infallible u16_pair u16_pair_split) 1689 1690(decl u8_pair (u8 u8) u16) 1691(extern constructor u8_pair u8_pair_concat) 1692(extern extractor infallible u8_pair u8_pair_split) 1693 1694(decl imm8x16 (u8 u8 u8 u8 u8 u8 u8 u8 u8 u8 u8 u8 u8 u8 u8 u8) u128) 1695(extractor (imm8x16 a b c d e f g h i j k l m n o p) 1696 (u64_pair (u32_pair (u16_pair (u8_pair a b) (u8_pair c d)) 1697 (u16_pair (u8_pair e f) (u8_pair g h))) 1698 (u32_pair (u16_pair (u8_pair i j) (u8_pair k l)) 1699 (u16_pair (u8_pair m n) (u8_pair o p))))) 1700(rule (imm8x16 a b c d e f g h i j k l m n o p) 1701 (u64_pair (u32_pair (u16_pair (u8_pair a b) (u8_pair c d)) 1702 (u16_pair (u8_pair e f) (u8_pair g h))) 1703 (u32_pair (u16_pair (u8_pair i j) (u8_pair k l)) 1704 (u16_pair (u8_pair m n) (u8_pair o p))))) 1705 1706;; Construct a VGBM mask to set all bits in one lane of a vector. 1707 1708(decl lane_byte_mask (Type u8) u16) 1709(extern constructor lane_byte_mask lane_byte_mask) 1710 1711;; Extract "permute" and "and" masks from a shuffle constant 1712 1713(decl shuffle_mask_from_u128 (u128 u16) u128) 1714(extern extractor infallible shuffle_mask_from_u128 shuffle_mask_from_u128) 1715 1716(decl shuffle_mask (u128 u16) Immediate) 1717(extractor (shuffle_mask permute_mask and_mask) 1718 (u128_from_immediate (shuffle_mask_from_u128 permute_mask and_mask))) 1719 1720;; Split an u64 into high and low parts. 1721 1722(decl u64_nonzero_hipart (u64) u64) 1723(extern extractor u64_nonzero_hipart u64_nonzero_hipart) 1724 1725(decl u64_nonzero_lopart (u64) u64) 1726(extern extractor u64_nonzero_lopart u64_nonzero_lopart) 1727 1728;; Extract smaller integer type from u64 if it matches. 1729 1730(decl uimm32shifted_from_u64 (UImm32Shifted) u64) 1731(extern extractor uimm32shifted_from_u64 uimm32shifted_from_u64) 1732 1733(decl uimm16shifted_from_u64 (UImm16Shifted) u64) 1734(extern extractor uimm16shifted_from_u64 uimm16shifted_from_u64) 1735 1736;; Extract integer of certain type from value if it matches. 1737 1738(decl u64_from_value (u64) Value) 1739(extern extractor u64_from_value u64_from_value) 1740 1741(decl u32_from_value (u32) Value) 1742(extern extractor u32_from_value u32_from_value) 1743 1744(decl u8_from_value (u8) Value) 1745(extern extractor u8_from_value u8_from_value) 1746 1747(decl u64_from_signed_value (u64) Value) 1748(extern extractor u64_from_signed_value u64_from_signed_value) 1749 1750(decl u64_from_inverted_value (u64) Value) 1751(extern extractor u64_from_inverted_value u64_from_inverted_value) 1752 1753(decl i64_from_value (i64) Value) 1754(extern extractor i64_from_value i64_from_value) 1755 1756(decl i32_from_value (i32) Value) 1757(extern extractor i32_from_value i32_from_value) 1758 1759(decl i16_from_value (i16) Value) 1760(extern extractor i16_from_value i16_from_value) 1761 1762(decl i16_from_swapped_value (i16) Value) 1763(extern extractor i16_from_swapped_value i16_from_swapped_value) 1764 1765(decl i64_from_negated_value (i64) Value) 1766(extern extractor i64_from_negated_value i64_from_negated_value) 1767 1768(decl i32_from_negated_value (i32) Value) 1769(extern extractor i32_from_negated_value i32_from_negated_value) 1770 1771(decl i16_from_negated_value (i16) Value) 1772(extern extractor i16_from_negated_value i16_from_negated_value) 1773 1774(decl uimm16shifted_from_value (UImm16Shifted) Value) 1775(extern extractor uimm16shifted_from_value uimm16shifted_from_value) 1776 1777(decl uimm32shifted_from_value (UImm32Shifted) Value) 1778(extern extractor uimm32shifted_from_value uimm32shifted_from_value) 1779 1780(decl uimm16shifted_from_inverted_value (UImm16Shifted) Value) 1781(extern extractor uimm16shifted_from_inverted_value uimm16shifted_from_inverted_value) 1782 1783(decl uimm32shifted_from_inverted_value (UImm32Shifted) Value) 1784(extern extractor uimm32shifted_from_inverted_value uimm32shifted_from_inverted_value) 1785 1786(decl len_minus_one (u8) u64) 1787(extern extractor len_minus_one len_minus_one) 1788 1789 1790;; Helpers for masking shift amounts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1791 1792;; Mask (immediate) shift amount to the type size. 1793(decl mask_amt_imm (Type i64) u8) 1794(extern constructor mask_amt_imm mask_amt_imm) 1795 1796;; Mask (immediate) shift amount to the type size. 1797;; Note that the hardware instructions always masks to six bits, so 1798;; in the case of a 64-bit type we do not need any explicit masking. 1799(decl mask_amt_reg (Type Reg) Reg) 1800(rule (mask_amt_reg (gpr32_ty ty) reg) 1801 (let ((mask u8 (mask_amt_imm ty -1))) 1802 (and_uimm16shifted ty reg (uimm16shifted mask 0)))) 1803(rule 1 (mask_amt_reg (gpr64_ty ty) reg) reg) 1804 1805;; Load a shift amount into a GPR. 1806(decl amt_reg (Value) Reg) 1807(rule 1 (amt_reg amt @ (value_type (fits_in_64 _))) amt) 1808(rule (amt_reg amt @ (value_type (vr128_ty _))) 1809 (vec_extract_lane $I64X2 amt 1 (zero_reg))) 1810 1811;; Load a shift amount into a VR, replicated across all 16 bytes. 1812(decl amt_vr (Value) Reg) 1813(rule (amt_vr amt @ (value_type (fits_in_64 _))) 1814 (vec_replicate_lane $I8X16 1815 (vec_insert_lane_undef $I8X16 amt 0 (zero_reg)) 0)) 1816(rule 1 (amt_vr amt @ (value_type (vr128_ty _))) 1817 (vec_replicate_lane $I8X16 amt 15)) 1818(rule 2 (amt_vr (u64_from_value amt)) 1819 (vec_imm_splat $I8X16 amt)) 1820 1821 1822;; Helpers for condition codes ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1823 1824(type Cond extern (enum)) 1825 1826(decl mask_as_cond (u8) Cond) 1827(extern constructor mask_as_cond mask_as_cond) 1828 1829(decl intcc_as_cond (IntCC) Cond) 1830(extern constructor intcc_as_cond intcc_as_cond) 1831 1832(decl floatcc_as_cond (FloatCC) Cond) 1833(extern constructor floatcc_as_cond floatcc_as_cond) 1834 1835(decl invert_cond (Cond) Cond) 1836(extern constructor invert_cond invert_cond) 1837 1838(decl signed () IntCC) 1839(extern extractor signed signed) 1840 1841(decl unsigned () IntCC) 1842(extern extractor unsigned unsigned) 1843 1844 1845;; Helpers for memory arguments ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1846 1847;; Accessors for `Offset32`. 1848 1849(decl zero_offset () Offset32) 1850(extern constructor zero_offset zero_offset) 1851 1852(decl i64_from_offset (i64) Offset32) 1853(extern extractor infallible i64_from_offset i64_from_offset) 1854 1855(type SImm20 extern (enum)) 1856 1857(decl pure partial memarg_imm_from_offset (SImm20) Offset32) 1858(extern extractor memarg_imm_from_offset memarg_imm_from_offset) 1859 1860(decl pure partial memarg_imm_from_offset_plus_bias (Offset32 u8) SImm20) 1861(extern constructor memarg_imm_from_offset_plus_bias memarg_imm_from_offset_plus_bias) 1862 1863;; Accessors for `MemFlags`. 1864 1865(decl littleendian () MemFlags) 1866(extern extractor littleendian littleendian) 1867 1868(decl bigendian () MemFlags) 1869(extern extractor bigendian bigendian) 1870 1871(decl memflags_trusted () MemFlags) 1872(extern constructor memflags_trusted memflags_trusted) 1873 1874;; Accessors for `MemArg`. 1875 1876(type MemArg extern (enum)) 1877 1878(decl memarg_reg_plus_reg_plus_off (Reg Reg SImm20 MemFlags) MemArg) 1879(extern constructor memarg_reg_plus_reg_plus_off memarg_reg_plus_reg_plus_off) 1880 1881(decl memarg_reg_plus_reg (Reg Reg u8 MemFlags) MemArg) 1882(extern constructor memarg_reg_plus_reg memarg_reg_plus_reg) 1883 1884(decl memarg_reg_plus_off (Reg i64 u8 MemFlags) MemArg) 1885(extern constructor memarg_reg_plus_off memarg_reg_plus_off) 1886 1887(decl memarg_symbol (ExternalName i32 MemFlags) MemArg) 1888(extern constructor memarg_symbol memarg_symbol) 1889 1890(decl memarg_got () MemArg) 1891(extern constructor memarg_got memarg_got) 1892 1893(decl memarg_const (VCodeConstant) MemArg) 1894(extern constructor memarg_const memarg_const) 1895 1896;; Form the sum of two offset values, and check that the result is 1897;; a valid `MemArg::Symbol` offset (i.e. is even and fits into i32). 1898(decl pure partial memarg_symbol_offset_sum (i64 i64) i32) 1899(extern constructor memarg_symbol_offset_sum memarg_symbol_offset_sum) 1900 1901;; Likewise, but just check a single offset value. 1902(decl pure partial memarg_symbol_offset (i64) i32) 1903(rule (memarg_symbol_offset x) 1904 (memarg_symbol_offset_sum x 0)) 1905 1906;; Create a MemArg referring to the saved frame pointer location. 1907(decl memarg_frame_pointer_offset () MemArg) 1908(extern constructor memarg_frame_pointer_offset memarg_frame_pointer_offset) 1909 1910;; Create a MemArg referring to the saved return address location. 1911(decl memarg_return_address_offset () MemArg) 1912(extern constructor memarg_return_address_offset memarg_return_address_offset) 1913 1914;; Lower an address into a `MemArg`. 1915 1916(decl lower_address (MemFlags Value Offset32) MemArg) 1917 1918(rule (lower_address flags addr @ (value_type (ty_addr64 _)) (i64_from_offset offset)) 1919 (memarg_reg_plus_off addr offset 0 flags)) 1920 1921(rule 1 (lower_address flags (has_type (ty_addr64 _) (iadd _ x y)) (memarg_imm_from_offset z)) 1922 (memarg_reg_plus_reg_plus_off x y z flags)) 1923 1924(rule 1 (lower_address flags 1925 (symbol_value _ (symbol_value_data name (RelocDistance.Near) sym_offset)) 1926 (i64_from_offset offset)) 1927 (if-let final_offset (memarg_symbol_offset_sum offset sym_offset)) 1928 (memarg_symbol name final_offset flags)) 1929 1930 1931;; Lower an address plus a small bias into a `MemArg`. 1932 1933(decl lower_address_bias (MemFlags Value Offset32 u8) MemArg) 1934 1935(rule (lower_address_bias flags addr @ (value_type $I64) (i64_from_offset offset) bias) 1936 (memarg_reg_plus_off addr offset bias flags)) 1937 1938(rule 1 (lower_address_bias flags (has_type $I64 (iadd _ x y)) z bias) 1939 (if-let final_offset (memarg_imm_from_offset_plus_bias z bias)) 1940 (memarg_reg_plus_reg_plus_off x y final_offset flags)) 1941 1942 1943;; Test whether a `load` address will be lowered to a `MemArg::Symbol`. 1944 1945(decl pure partial load_sym (Inst) Inst) 1946(rule (load_sym inst) 1947 (if-let (load _ _ (symbol_value _ (symbol_value_data _ (RelocDistance.Near) sym_offset)) 1948 (i64_from_offset load_offset)) 1949 inst) 1950 (if (memarg_symbol_offset_sum sym_offset load_offset)) 1951 inst) 1952 1953(decl pure partial uload16_sym (Inst) Inst) 1954(rule (uload16_sym inst) 1955 (if-let (uload16 _ _ (symbol_value _ (symbol_value_data _ (RelocDistance.Near) sym_offset)) 1956 (i64_from_offset load_offset)) 1957 inst) 1958 (if (memarg_symbol_offset_sum sym_offset load_offset)) 1959 inst) 1960 1961 1962;; Helpers for stack-slot addresses ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1963 1964(decl stack_addr_impl (Type StackSlot Offset32) Reg) 1965(rule (stack_addr_impl ty stack_slot offset) 1966 (let ((dst WritableReg (temp_writable_reg ty)) 1967 (_ Unit (emit (abi_stackslot_addr dst stack_slot offset)))) 1968 dst)) 1969 1970 1971;; Helpers for extracting extensions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1972 1973;; A value that is the result of a sign-extend from a 32-bit value. 1974(decl sext32_value (Value) Value) 1975(extractor (sext32_value x) (sextend _ (and x (value_type $I32)))) 1976 1977;; A value that is the result of a zero-extend from a 32-bit value. 1978(decl zext32_value (Value) Value) 1979(extractor (zext32_value x) (uextend _ (and x (value_type $I32)))) 1980 1981 1982;; Helpers for sinkable loads ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 1983 1984;; Extract a sinkable instruction from a value operand. 1985(decl sinkable_inst (Inst) Value) 1986(extern extractor sinkable_inst sinkable_inst) 1987 1988;; Sinkable big-endian load instruction. 1989(decl sinkable_load (Inst) Value) 1990(extractor (sinkable_load inst) 1991 (sinkable_inst (and inst (load _ (bigendian) _addr _offset)))) 1992 1993;; Sinkable big-endian load instruction (32/64-bit types only). 1994(decl sinkable_load_32_64 (Inst) Value) 1995(extractor (sinkable_load_32_64 inst) 1996 (and (value_type (ty_32_or_64 _)) (sinkable_load inst))) 1997 1998;; Sinkable big-endian load instruction (16-bit types only). 1999(decl sinkable_load_16 (Inst) Value) 2000(extractor (sinkable_load_16 inst) 2001 (and (value_type $I16) (sinkable_load inst))) 2002 2003;; Sinkable little-endian load instruction. 2004(decl sinkable_load_little (Inst) Value) 2005(extractor (sinkable_load_little inst) 2006 (sinkable_inst (and inst (load _ (littleendian) _addr _offset)))) 2007 2008;; Sinkable big-endian sload16 instruction. 2009(decl sinkable_sload16 (Inst) Value) 2010(extractor (sinkable_sload16 inst) 2011 (sinkable_inst (and inst (sload16 _ (bigendian) _addr _offset)))) 2012 2013;; Sinkable big-endian sload32 instruction. 2014(decl sinkable_sload32 (Inst) Value) 2015(extractor (sinkable_sload32 inst) 2016 (sinkable_inst (and inst (sload32 _ (bigendian) _addr _offset)))) 2017 2018;; Sinkable big-endian uload16 instruction. 2019(decl sinkable_uload16 (Inst) Value) 2020(extractor (sinkable_uload16 inst) 2021 (sinkable_inst (and inst (uload16 _ (bigendian) _addr _offset)))) 2022 2023;; Sinkable big-endian uload32 instruction. 2024(decl sinkable_uload32 (Inst) Value) 2025(extractor (sinkable_uload32 inst) 2026 (sinkable_inst (and inst (uload32 _ (bigendian) _addr _offset)))) 2027 2028;; Sink a load instruction, returning its address as `MemArg`. 2029;; This is a side-effectful operation, see `sink_inst`. 2030(decl sink_load (Inst) MemArg) 2031(rule (sink_load inst @ (load _ flags addr offset)) 2032 (let ((_ Unit (sink_inst inst))) 2033 (lower_address flags addr offset))) 2034 2035;; Sink a sload16 instruction, returning its address as `MemArg`. 2036;; This is a side-effectful operation, see `sink_inst`. 2037(decl sink_sload16 (Inst) MemArg) 2038(rule (sink_sload16 inst @ (sload16 _ flags addr offset)) 2039 (let ((_ Unit (sink_inst inst))) 2040 (lower_address flags addr offset))) 2041 2042;; Sink a sload32 instruction, returning its address as `MemArg`. 2043;; This is a side-effectful operation, see `sink_inst`. 2044(decl sink_sload32 (Inst) MemArg) 2045(rule (sink_sload32 inst @ (sload32 _ flags addr offset)) 2046 (let ((_ Unit (sink_inst inst))) 2047 (lower_address flags addr offset))) 2048 2049;; Sink a uload16 instruction, returning its address as `MemArg`. 2050;; This is a side-effectful operation, see `sink_inst`. 2051(decl sink_uload16 (Inst) MemArg) 2052(rule (sink_uload16 inst @ (uload16 _ flags addr offset)) 2053 (let ((_ Unit (sink_inst inst))) 2054 (lower_address flags addr offset))) 2055 2056;; Sink a uload32 instruction, returning its address as `MemArg`. 2057;; This is a side-effectful operation, see `sink_inst`. 2058(decl sink_uload32 (Inst) MemArg) 2059(rule (sink_uload32 inst @ (uload32 _ flags addr offset)) 2060 (let ((_ Unit (sink_inst inst))) 2061 (lower_address flags addr offset))) 2062 2063 2064;; Helpers for register pairs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2065 2066;; A writable register pair. 2067(type WritableRegPair (primitive WritableRegPair)) 2068 2069;; Construct a WritableRegPair from two registers. 2070(decl writable_regpair (WritableReg WritableReg) WritableRegPair) 2071(extern constructor writable_regpair writable_regpair) 2072 2073;; Allocate a writable register pair. 2074(decl temp_writable_regpair (Type) WritableRegPair) 2075(rule (temp_writable_regpair ty) 2076 (writable_regpair (temp_writable_reg ty) (temp_writable_reg ty))) 2077 2078;; Retrieve the high word of the writable register pair. 2079(decl writable_regpair_hi (WritableRegPair) WritableReg) 2080(extern constructor writable_regpair_hi writable_regpair_hi) 2081 2082;; Retrieve the low word of the writable register pair. 2083(decl writable_regpair_lo (WritableRegPair) WritableReg) 2084(extern constructor writable_regpair_lo writable_regpair_lo) 2085 2086;; A (read-only) register pair. 2087(type RegPair (primitive RegPair)) 2088 2089;; Construct a register pair from a writable register pair. 2090(decl writable_regpair_to_regpair (WritableRegPair) RegPair) 2091(rule (writable_regpair_to_regpair w) 2092 (regpair (writable_regpair_hi w) (writable_regpair_lo w))) 2093 2094;; Construct a regpair from two registers. 2095(decl regpair (Reg Reg) RegPair) 2096(extern constructor regpair regpair) 2097 2098;; Retrieve the high word of the register pair. 2099(decl regpair_hi (RegPair) Reg) 2100(extern constructor regpair_hi regpair_hi) 2101 2102;; Retrieve the low word of the register pair. 2103(decl regpair_lo (RegPair) Reg) 2104(extern constructor regpair_lo regpair_lo) 2105 2106;; Move a $F128 value between a single VR and a pair of FPRs. 2107(decl fp_reg_to_regpair (Reg) RegPair) 2108(rule (fp_reg_to_regpair x) (regpair x (vec_replicate_lane $I64X2 x 1))) 2109(decl fp_regpair_to_reg (RegPair) Reg) 2110(rule (fp_regpair_to_reg x) (vec_merge_high $I64X2 (regpair_hi x) (regpair_lo x))) 2111 2112 2113;; Instruction creation helpers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2114 2115;; Helper for emitting `MInst.AluRRR` instructions. 2116(decl alu_rrr (Type ALUOp Reg Reg) Reg) 2117(rule (alu_rrr ty op src1 src2) 2118 (let ((dst WritableReg (temp_writable_reg ty)) 2119 (_ Unit (emit (MInst.AluRRR op dst src1 src2)))) 2120 dst)) 2121 2122;; Helper for emitting `MInst.AluRRR` instructions as flag producers. 2123(decl alu_rrr_with_flags_paired (Type ALUOp Reg Reg) ProducesFlags) 2124(rule (alu_rrr_with_flags_paired ty op src1 src2) 2125 (let ((dst WritableReg (temp_writable_reg ty))) 2126 (ProducesFlags.ProducesFlagsReturnsResultWithConsumer 2127 (MInst.AluRRR op dst src1 src2) dst))) 2128 2129;; Helper for emitting `MInst.AluRRSImm16` instructions. 2130(decl alu_rrsimm16 (Type ALUOp Reg i16) Reg) 2131(rule (alu_rrsimm16 ty op src imm) 2132 (let ((dst WritableReg (temp_writable_reg ty)) 2133 (_ Unit (emit (MInst.AluRRSImm16 op dst src imm)))) 2134 dst)) 2135 2136;; Helper for emitting `MInst.AluRR` instructions. 2137(decl alu_rr (Type ALUOp Reg Reg) Reg) 2138(rule (alu_rr ty op src1 src2) 2139 (let ((dst WritableReg (temp_writable_reg ty)) 2140 (_ Unit (emit (MInst.AluRR op dst src1 src2)))) 2141 dst)) 2142 2143;; Helper for emitting `MInst.AluRR` instructions as flag producers. 2144(decl alu_rr_with_flags_paired (Type ALUOp Reg Reg) ProducesFlags) 2145(rule (alu_rr_with_flags_paired ty op src1 src2) 2146 (let ((dst WritableReg (temp_writable_reg ty))) 2147 (ProducesFlags.ProducesFlagsReturnsResultWithConsumer 2148 (MInst.AluRR op dst src1 src2) dst))) 2149 2150;; Helper for emitting `MInst.AluRX` instructions. 2151(decl alu_rx (Type ALUOp Reg MemArg) Reg) 2152(rule (alu_rx ty op src mem) 2153 (let ((dst WritableReg (temp_writable_reg ty)) 2154 (_ Unit (emit (MInst.AluRX op dst src mem)))) 2155 dst)) 2156 2157;; Helper for emitting `MInst.AluRX` instructions as flags producers. 2158(decl alu_rx_with_flags_paired (Type ALUOp Reg MemArg) ProducesFlags) 2159(rule (alu_rx_with_flags_paired ty op src mem) 2160 (let ((dst WritableReg (temp_writable_reg ty))) 2161 (ProducesFlags.ProducesFlagsReturnsResultWithConsumer 2162 (MInst.AluRX op dst src mem) dst))) 2163 2164;; Helper for emitting `MInst.AluRSImm16` instructions. 2165(decl alu_rsimm16 (Type ALUOp Reg i16) Reg) 2166(rule (alu_rsimm16 ty op src imm) 2167 (let ((dst WritableReg (temp_writable_reg ty)) 2168 (_ Unit (emit (MInst.AluRSImm16 op dst src imm)))) 2169 dst)) 2170 2171;; Helper for emitting `MInst.AluRSImm32` instructions. 2172(decl alu_rsimm32 (Type ALUOp Reg i32) Reg) 2173(rule (alu_rsimm32 ty op src imm) 2174 (let ((dst WritableReg (temp_writable_reg ty)) 2175 (_ Unit (emit (MInst.AluRSImm32 op dst src imm)))) 2176 dst)) 2177 2178;; Helper for emitting `MInst.AluRUImm32` instructions. 2179(decl alu_ruimm32 (Type ALUOp Reg u32) Reg) 2180(rule (alu_ruimm32 ty op src imm) 2181 (let ((dst WritableReg (temp_writable_reg ty)) 2182 (_ Unit (emit (MInst.AluRUImm32 op dst src imm)))) 2183 dst)) 2184 2185;; Helper for emitting `MInst.AluRUImm32` instructions as flag producers. 2186(decl alu_ruimm32_with_flags_paired (Type ALUOp Reg u32) ProducesFlags) 2187(rule (alu_ruimm32_with_flags_paired ty op src imm) 2188 (let ((dst WritableReg (temp_writable_reg ty))) 2189 (ProducesFlags.ProducesFlagsReturnsResultWithConsumer 2190 (MInst.AluRUImm32 op dst src imm) dst))) 2191 2192;; Helper for emitting `MInst.AluRUImm16Shifted` instructions. 2193(decl alu_ruimm16shifted (Type ALUOp Reg UImm16Shifted) Reg) 2194(rule (alu_ruimm16shifted ty op src imm) 2195 (let ((dst WritableReg (temp_writable_reg ty)) 2196 (_ Unit (emit (MInst.AluRUImm16Shifted op dst src imm)))) 2197 dst)) 2198 2199;; Helper for emitting `MInst.AluRUImm32Shifted` instructions. 2200(decl alu_ruimm32shifted (Type ALUOp Reg UImm32Shifted) Reg) 2201(rule (alu_ruimm32shifted ty op src imm) 2202 (let ((dst WritableReg (temp_writable_reg ty)) 2203 (_ Unit (emit (MInst.AluRUImm32Shifted op dst src imm)))) 2204 dst)) 2205 2206;; Helper for emitting `MInst.SMulWide` instructions. 2207(decl smul_wide (Reg Reg) RegPair) 2208(rule (smul_wide src1 src2) 2209 (let ((dst WritableRegPair (temp_writable_regpair $I64)) 2210 (_ Unit (emit (MInst.SMulWide dst src1 src2)))) 2211 dst)) 2212 2213;; Helper for emitting `MInst.UMulWide` instructions. 2214(decl umul_wide (Reg Reg) RegPair) 2215(rule (umul_wide src1 src2) 2216 (let ((dst WritableRegPair (temp_writable_regpair $I64)) 2217 (_ Unit (emit (MInst.UMulWide dst src1 src2)))) 2218 dst)) 2219 2220;; Helper for emitting `MInst.SDivMod32` instructions. 2221(decl sdivmod32 (Reg Reg) RegPair) 2222(rule (sdivmod32 src1 src2) 2223 (let ((dst WritableRegPair (temp_writable_regpair $I64)) 2224 (_ Unit (emit (MInst.SDivMod32 dst src1 src2)))) 2225 dst)) 2226 2227;; Helper for emitting `MInst.SDivMod64` instructions. 2228(decl sdivmod64 (Reg Reg) RegPair) 2229(rule (sdivmod64 src1 src2) 2230 (let ((dst WritableRegPair (temp_writable_regpair $I64)) 2231 (_ Unit (emit (MInst.SDivMod64 dst src1 src2)))) 2232 dst)) 2233 2234;; Helper for emitting `MInst.UDivMod32` instructions. 2235(decl udivmod32 (RegPair Reg) RegPair) 2236(rule (udivmod32 src1 src2) 2237 (let ((dst WritableRegPair (temp_writable_regpair $I64)) 2238 (_ Unit (emit (MInst.UDivMod32 dst src1 src2)))) 2239 dst)) 2240 2241;; Helper for emitting `MInst.UDivMod64` instructions. 2242(decl udivmod64 (RegPair Reg) RegPair) 2243(rule (udivmod64 src1 src2) 2244 (let ((dst WritableRegPair (temp_writable_regpair $I64)) 2245 (_ Unit (emit (MInst.UDivMod64 dst src1 src2)))) 2246 dst)) 2247 2248;; Helper for emitting `MInst.ShiftRR` instructions. 2249(decl shift_rr (Type ShiftOp Reg u8 Reg) Reg) 2250(rule (shift_rr ty op src shift_imm shift_reg) 2251 (let ((dst WritableReg (temp_writable_reg ty)) 2252 (_ Unit (emit (MInst.ShiftRR op dst src shift_imm shift_reg)))) 2253 dst)) 2254 2255;; Helper for emitting `MInst.RxSBGTest` instructions. 2256(decl rxsbg_test (RxSBGOp Reg Reg u8 u8 i8) ProducesFlags) 2257(rule (rxsbg_test op src1 src2 start_bit end_bit rotate_amt) 2258 (ProducesFlags.ProducesFlagsSideEffect 2259 (MInst.RxSBGTest op src1 src2 start_bit end_bit rotate_amt))) 2260 2261;; Helper for emitting `MInst.UnaryRR` instructions. 2262(decl unary_rr (Type UnaryOp Reg) Reg) 2263(rule (unary_rr ty op src) 2264 (let ((dst WritableReg (temp_writable_reg ty)) 2265 (_ Unit (emit (MInst.UnaryRR op dst src)))) 2266 dst)) 2267 2268;; Helper for emitting `MInst.CmpRR` instructions. 2269(decl cmp_rr (CmpOp Reg Reg) ProducesFlags) 2270(rule (cmp_rr op src1 src2) 2271 (ProducesFlags.ProducesFlagsSideEffect (MInst.CmpRR op src1 src2))) 2272 2273;; Helper for emitting `MInst.CmpRX` instructions. 2274(decl cmp_rx (CmpOp Reg MemArg) ProducesFlags) 2275(rule (cmp_rx op src mem) 2276 (ProducesFlags.ProducesFlagsSideEffect (MInst.CmpRX op src mem))) 2277 2278;; Helper for emitting `MInst.CmpRSImm16` instructions. 2279(decl cmp_rsimm16 (CmpOp Reg i16) ProducesFlags) 2280(rule (cmp_rsimm16 op src imm) 2281 (ProducesFlags.ProducesFlagsSideEffect (MInst.CmpRSImm16 op src imm))) 2282 2283;; Helper for emitting `MInst.CmpRSImm32` instructions. 2284(decl cmp_rsimm32 (CmpOp Reg i32) ProducesFlags) 2285(rule (cmp_rsimm32 op src imm) 2286 (ProducesFlags.ProducesFlagsSideEffect (MInst.CmpRSImm32 op src imm))) 2287 2288;; Helper for emitting `MInst.CmpRUImm32` instructions. 2289(decl cmp_ruimm32 (CmpOp Reg u32) ProducesFlags) 2290(rule (cmp_ruimm32 op src imm) 2291 (ProducesFlags.ProducesFlagsSideEffect (MInst.CmpRUImm32 op src imm))) 2292 2293;; Helper for emitting `MInst.AtomicRmw` instructions. 2294(decl atomic_rmw_impl (Type ALUOp Reg MemArg) Reg) 2295(rule (atomic_rmw_impl ty op src mem) 2296 (let ((dst WritableReg (temp_writable_reg ty)) 2297 (_ Unit (emit (MInst.AtomicRmw op dst src mem)))) 2298 dst)) 2299 2300;; Helper for emitting `MInst.AtomicCas32` instructions. 2301(decl atomic_cas32 (Reg Reg MemArg) Reg) 2302(rule (atomic_cas32 src1 src2 mem) 2303 (let ((dst WritableReg (temp_writable_reg $I32)) 2304 (_ Unit (emit (MInst.AtomicCas32 dst src1 src2 mem)))) 2305 dst)) 2306 2307;; Helper for emitting `MInst.AtomicCas64` instructions. 2308(decl atomic_cas64 (Reg Reg MemArg) Reg) 2309(rule (atomic_cas64 src1 src2 mem) 2310 (let ((dst WritableReg (temp_writable_reg $I64)) 2311 (_ Unit (emit (MInst.AtomicCas64 dst src1 src2 mem)))) 2312 dst)) 2313 2314;; Helper for emitting `MInst.Fence` instructions. 2315(decl fence_impl () SideEffectNoResult) 2316(rule (fence_impl) 2317 (SideEffectNoResult.Inst (MInst.Fence))) 2318 2319;; Helper for emitting `MInst.Load32` instructions. 2320(decl load32 (MemArg) Reg) 2321(rule (load32 addr) 2322 (let ((dst WritableReg (temp_writable_reg $I32)) 2323 (_ Unit (emit (MInst.Load32 dst addr)))) 2324 dst)) 2325 2326;; Helper for emitting `MInst.Load64` instructions. 2327(decl load64 (MemArg) Reg) 2328(rule (load64 addr) 2329 (let ((dst WritableReg (temp_writable_reg $I64)) 2330 (_ Unit (emit (MInst.Load64 dst addr)))) 2331 dst)) 2332 2333;; Helper for emitting `MInst.LoadRev16` instructions. 2334(decl loadrev16 (MemArg) Reg) 2335(rule (loadrev16 addr) 2336 (let ((dst WritableReg (temp_writable_reg $I32)) 2337 (_ Unit (emit (MInst.LoadRev16 dst addr)))) 2338 dst)) 2339 2340;; Helper for emitting `MInst.LoadRev32` instructions. 2341(decl loadrev32 (MemArg) Reg) 2342(rule (loadrev32 addr) 2343 (let ((dst WritableReg (temp_writable_reg $I32)) 2344 (_ Unit (emit (MInst.LoadRev32 dst addr)))) 2345 dst)) 2346 2347;; Helper for emitting `MInst.LoadRev64` instructions. 2348(decl loadrev64 (MemArg) Reg) 2349(rule (loadrev64 addr) 2350 (let ((dst WritableReg (temp_writable_reg $I64)) 2351 (_ Unit (emit (MInst.LoadRev64 dst addr)))) 2352 dst)) 2353 2354;; Helper for emitting `MInst.Store8` instructions. 2355(decl store8 (Reg MemArg) SideEffectNoResult) 2356(rule (store8 src addr) 2357 (SideEffectNoResult.Inst (MInst.Store8 src addr))) 2358 2359;; Helper for emitting `MInst.Store16` instructions. 2360(decl store16 (Reg MemArg) SideEffectNoResult) 2361(rule (store16 src addr) 2362 (SideEffectNoResult.Inst (MInst.Store16 src addr))) 2363 2364;; Helper for emitting `MInst.Store32` instructions. 2365(decl store32 (Reg MemArg) SideEffectNoResult) 2366(rule (store32 src addr) 2367 (SideEffectNoResult.Inst (MInst.Store32 src addr))) 2368 2369;; Helper for emitting `MInst.Store64` instructions. 2370(decl store64 (Reg MemArg) SideEffectNoResult) 2371(rule (store64 src addr) 2372 (SideEffectNoResult.Inst (MInst.Store64 src addr))) 2373 2374;; Helper for emitting `MInst.StoreImm8` instructions. 2375(decl store8_imm (u8 MemArg) SideEffectNoResult) 2376(rule (store8_imm imm addr) 2377 (SideEffectNoResult.Inst (MInst.StoreImm8 imm addr))) 2378 2379;; Helper for emitting `MInst.StoreImm16` instructions. 2380(decl store16_imm (i16 MemArg) SideEffectNoResult) 2381(rule (store16_imm imm addr) 2382 (SideEffectNoResult.Inst (MInst.StoreImm16 imm addr))) 2383 2384;; Helper for emitting `MInst.StoreImm32SExt16` instructions. 2385(decl store32_simm16 (i16 MemArg) SideEffectNoResult) 2386(rule (store32_simm16 imm addr) 2387 (SideEffectNoResult.Inst (MInst.StoreImm32SExt16 imm addr))) 2388 2389;; Helper for emitting `MInst.StoreImm64SExt16` instructions. 2390(decl store64_simm16 (i16 MemArg) SideEffectNoResult) 2391(rule (store64_simm16 imm addr) 2392 (SideEffectNoResult.Inst (MInst.StoreImm64SExt16 imm addr))) 2393 2394;; Helper for emitting `MInst.StoreRev16` instructions. 2395(decl storerev16 (Reg MemArg) SideEffectNoResult) 2396(rule (storerev16 src addr) 2397 (SideEffectNoResult.Inst (MInst.StoreRev16 src addr))) 2398 2399;; Helper for emitting `MInst.StoreRev32` instructions. 2400(decl storerev32 (Reg MemArg) SideEffectNoResult) 2401(rule (storerev32 src addr) 2402 (SideEffectNoResult.Inst (MInst.StoreRev32 src addr))) 2403 2404;; Helper for emitting `MInst.StoreRev64` instructions. 2405(decl storerev64 (Reg MemArg) SideEffectNoResult) 2406(rule (storerev64 src addr) 2407 (SideEffectNoResult.Inst (MInst.StoreRev64 src addr))) 2408 2409;; Helper for emitting `MInst.LoadAR` instructions. 2410(decl load_ar (u8) Reg) 2411(rule (load_ar ar) 2412 (let ((dst WritableReg (temp_writable_reg $I64)) 2413 (_ Unit (emit (MInst.LoadAR dst ar)))) 2414 dst)) 2415 2416;; Helper for emitting `MInst.InsertAR` instructions. 2417(decl insert_ar (Reg u8) Reg) 2418(rule (insert_ar src ar) 2419 (let ((dst WritableReg (temp_writable_reg $I64)) 2420 (_ Unit (emit (MInst.InsertAR dst src ar)))) 2421 dst)) 2422 2423;; Helper for emitting `MInst.FpuRR` instructions. 2424(decl fpu_rr (Type FPUOp1 Reg) Reg) 2425(rule (fpu_rr ty op src) 2426 (let ((dst WritableReg (temp_writable_reg ty)) 2427 (_ Unit (emit (MInst.FpuRR op dst src)))) 2428 dst)) 2429 2430;; Helper for emitting `MInst.FpuRRR` instructions. 2431(decl fpu_rrr (Type FPUOp2 Reg Reg) Reg) 2432(rule (fpu_rrr ty op src1 src2) 2433 (let ((dst WritableReg (temp_writable_reg ty)) 2434 (_ Unit (emit (MInst.FpuRRR op dst src1 src2)))) 2435 dst)) 2436 2437;; Helper for emitting `MInst.FpuRRRR` instructions. 2438(decl fpu_rrrr (Type FPUOp3 Reg Reg Reg) Reg) 2439(rule (fpu_rrrr ty op src1 src2 src3) 2440 (let ((dst WritableReg (temp_writable_reg ty)) 2441 (_ Unit (emit (MInst.FpuRRRR op dst src1 src2 src3)))) 2442 dst)) 2443 2444;; Helper for emitting `MInst.FpuCmp32` instructions. 2445(decl fpu_cmp32 (Reg Reg) ProducesFlags) 2446(rule (fpu_cmp32 src1 src2) 2447 (ProducesFlags.ProducesFlagsSideEffect (MInst.FpuCmp32 src1 src2))) 2448 2449;; Helper for emitting `MInst.FpuCmp64` instructions. 2450(decl fpu_cmp64 (Reg Reg) ProducesFlags) 2451(rule (fpu_cmp64 src1 src2) 2452 (ProducesFlags.ProducesFlagsSideEffect (MInst.FpuCmp64 src1 src2))) 2453 2454;; Helper for emitting `MInst.FpuCmp128` instructions. 2455(decl fpu_cmp128 (Reg Reg) ProducesFlags) 2456(rule (fpu_cmp128 src1 src2) 2457 (ProducesFlags.ProducesFlagsSideEffect (MInst.FpuCmp128 src1 src2))) 2458 2459;; Helper for emitting `MInst.FpuRound` instructions. 2460(decl fpu_round (Type FpuRoundOp FpuRoundMode Reg) Reg) 2461(rule (fpu_round ty op mode src) 2462 (let ((dst WritableReg (temp_writable_reg ty)) 2463 (_ Unit (emit (MInst.FpuRound op mode dst src)))) 2464 dst)) 2465 2466;; Helper for emitting `MInst.FpuConv128FromInt` instructions. 2467(decl fpu_conv128_from_int (FpuConv128Op FpuRoundMode Reg) RegPair) 2468(rule (fpu_conv128_from_int op mode src) 2469 (let ((dst WritableRegPair (temp_writable_regpair $F64)) 2470 (_ Unit (emit (MInst.FpuConv128FromInt op mode dst src)))) 2471 dst)) 2472 2473;; Helper for emitting `MInst.FpuConv128ToInt` instructions. 2474(decl fpu_conv128_to_int (Type FpuConv128Op FpuRoundMode RegPair) Reg) 2475(rule (fpu_conv128_to_int ty op mode src) 2476 (let ((dst WritableReg (temp_writable_reg ty)) 2477 (_ Unit (emit (MInst.FpuConv128ToInt op mode dst src)))) 2478 dst)) 2479 2480;; Helper for emitting `MInst.VecRRR` instructions. 2481(decl vec_rrr (Type VecBinaryOp Reg Reg) Reg) 2482(rule (vec_rrr ty op src1 src2) 2483 (let ((dst WritableReg (temp_writable_reg ty)) 2484 (_ Unit (emit (MInst.VecRRR op dst src1 src2)))) 2485 dst)) 2486 2487;; Helper for emitting `MInst.VecRR` instructions. 2488(decl vec_rr (Type VecUnaryOp Reg) Reg) 2489(rule (vec_rr ty op src) 2490 (let ((dst WritableReg (temp_writable_reg ty)) 2491 (_ Unit (emit (MInst.VecRR op dst src)))) 2492 dst)) 2493 2494;; Helper for emitting `MInst.VecShiftRR` instructions. 2495(decl vec_shift_rr (Type VecShiftOp Reg u8 Reg) Reg) 2496(rule (vec_shift_rr ty op src shift_imm shift_reg) 2497 (let ((dst WritableReg (temp_writable_reg ty)) 2498 (_ Unit (emit (MInst.VecShiftRR op dst src shift_imm shift_reg)))) 2499 dst)) 2500 2501;; Helper for emitting `MInst.VecSelect` instructions. 2502(decl vec_select (Type Reg Reg Reg) Reg) 2503(rule (vec_select ty src1 src2 src3) 2504 (let ((dst WritableReg (temp_writable_reg ty)) 2505 (_ Unit (emit (MInst.VecSelect dst src1 src2 src3)))) 2506 dst)) 2507 2508;; Helper for emitting `MInst.VecPermute` instructions. 2509(decl vec_permute (Type Reg Reg Reg) Reg) 2510(rule (vec_permute ty src1 src2 src3) 2511 (let ((dst WritableReg (temp_writable_reg ty)) 2512 (_ Unit (emit (MInst.VecPermute dst src1 src2 src3)))) 2513 dst)) 2514 2515;; Helper for emitting `MInst.VecBlend` instructions. 2516(decl vec_blend (Type Reg Reg Reg) Reg) 2517(rule (vec_blend ty src1 src2 src3) 2518 (let ((dst WritableReg (temp_writable_reg ty)) 2519 (_ Unit (emit (MInst.VecBlend dst src1 src2 src3)))) 2520 dst)) 2521 2522;; Helper for emitting `MInst.VecEvaluate` instructions. 2523(decl vec_eval (Type u8 Reg Reg Reg) Reg) 2524(rule (vec_eval ty op src1 src2 src3) 2525 (let ((dst WritableReg (temp_writable_reg ty)) 2526 (_ Unit (emit (MInst.VecEvaluate op dst src1 src2 src3)))) 2527 dst)) 2528 2529;; Helper for emitting `MInst.VecPermuteDWImm` instructions. 2530(decl vec_permute_dw_imm (Type Reg u8 Reg u8) Reg) 2531(rule (vec_permute_dw_imm ty src1 idx1 src2 idx2) 2532 (let ((dst WritableReg (temp_writable_reg ty)) 2533 (_ Unit (emit (MInst.VecPermuteDWImm dst src1 src2 idx1 idx2)))) 2534 dst)) 2535 2536;; Helper for emitting `MInst.VecIntCmp` instructions. 2537(decl vec_int_cmp (Type VecIntCmpOp Reg Reg) Reg) 2538(rule (vec_int_cmp ty op src1 src2) 2539 (let ((dst WritableReg (temp_writable_reg ty)) 2540 (_ Unit (emit (MInst.VecIntCmp op dst src1 src2)))) 2541 dst)) 2542 2543;; Helper for emitting `MInst.VecIntCmpS` instructions. 2544(decl vec_int_cmps (Type VecIntCmpOp Reg Reg) ProducesFlags) 2545(rule (vec_int_cmps ty op src1 src2) 2546 (let ((tmp WritableReg (temp_writable_reg ty))) 2547 (ProducesFlags.ProducesFlagsSideEffect (MInst.VecIntCmpS op tmp src1 src2)))) 2548 2549;; Helper for emitting `MInst.VecFloatCmp` instructions. 2550(decl vec_float_cmp (Type VecFloatCmpOp Reg Reg) Reg) 2551(rule (vec_float_cmp ty op src1 src2) 2552 (let ((dst WritableReg (temp_writable_reg ty)) 2553 (_ Unit (emit (MInst.VecFloatCmp op dst src1 src2)))) 2554 dst)) 2555 2556;; Helper for emitting `MInst.VecFloatCmpS` instructions. 2557(decl vec_float_cmps (Type VecFloatCmpOp Reg Reg) ProducesFlags) 2558(rule (vec_float_cmps ty op src1 src2) 2559 (let ((tmp WritableReg (temp_writable_reg ty))) 2560 (ProducesFlags.ProducesFlagsSideEffect (MInst.VecFloatCmpS op tmp src1 src2)))) 2561 2562;; Helper for emitting `MInst.VecIntEltCmp` instructions. 2563(decl vec_int_elt_cmp (VecIntEltCmpOp Reg Reg) ProducesFlags) 2564(rule (vec_int_elt_cmp op src1 src2) 2565 (ProducesFlags.ProducesFlagsSideEffect (MInst.VecIntEltCmp op src1 src2))) 2566 2567;; Helper for emitting `MInst.VecInt128SCmpHi` instructions. 2568(decl vec_int128_scmphi (Reg Reg) ProducesBool) 2569(rule (vec_int128_scmphi src1 src2) 2570 (let ((tmp WritableReg (temp_writable_reg $I128))) 2571 (bool (ProducesFlags.ProducesFlagsSideEffect (MInst.VecInt128SCmpHi tmp src1 src2)) 2572 (mask_as_cond 4)))) 2573 2574;; Helper for emitting `MInst.VecInt128UCmpHi` instructions. 2575(decl vec_int128_ucmphi (Reg Reg) ProducesBool) 2576(rule (vec_int128_ucmphi src1 src2) 2577 (let ((tmp WritableReg (temp_writable_reg $I128))) 2578 (bool (ProducesFlags.ProducesFlagsSideEffect (MInst.VecInt128UCmpHi tmp src1 src2)) 2579 (mask_as_cond 4)))) 2580 2581;; Helper for emitting `MInst.VecLoad` instructions. 2582(decl vec_load (Type MemArg) Reg) 2583(rule (vec_load ty addr) 2584 (let ((dst WritableReg (temp_writable_reg ty)) 2585 (_ Unit (emit (MInst.VecLoad dst addr)))) 2586 dst)) 2587 2588;; Helper for emitting `MInst.VecLoadRev` instructions. 2589(decl vec_loadrev (Type MemArg) Reg) 2590(rule (vec_loadrev ty addr) 2591 (let ((dst WritableReg (temp_writable_reg ty)) 2592 (_ Unit (emit (MInst.VecLoadRev dst addr)))) 2593 dst)) 2594 2595;; Helper for emitting `MInst.VecLoadByte16Rev` instructions. 2596(decl vec_load_byte16rev (Type MemArg) Reg) 2597(rule (vec_load_byte16rev ty addr) 2598 (let ((dst WritableReg (temp_writable_reg ty)) 2599 (_ Unit (emit (MInst.VecLoadByte16Rev dst addr)))) 2600 dst)) 2601 2602;; Helper for emitting `MInst.VecLoadByte32Rev` instructions. 2603(decl vec_load_byte32rev (Type MemArg) Reg) 2604(rule (vec_load_byte32rev ty addr) 2605 (let ((dst WritableReg (temp_writable_reg ty)) 2606 (_ Unit (emit (MInst.VecLoadByte32Rev dst addr)))) 2607 dst)) 2608 2609;; Helper for emitting `MInst.VecLoadByte64Rev` instructions. 2610(decl vec_load_byte64rev (Type MemArg) Reg) 2611(rule (vec_load_byte64rev ty addr) 2612 (let ((dst WritableReg (temp_writable_reg ty)) 2613 (_ Unit (emit (MInst.VecLoadByte64Rev dst addr)))) 2614 dst)) 2615 2616;; Helper for emitting `MInst.VecLoadElt16Rev` instructions. 2617(decl vec_load_elt16rev (Type MemArg) Reg) 2618(rule (vec_load_elt16rev ty addr) 2619 (let ((dst WritableReg (temp_writable_reg ty)) 2620 (_ Unit (emit (MInst.VecLoadElt16Rev dst addr)))) 2621 dst)) 2622 2623;; Helper for emitting `MInst.VecLoadElt32Rev` instructions. 2624(decl vec_load_elt32rev (Type MemArg) Reg) 2625(rule (vec_load_elt32rev ty addr) 2626 (let ((dst WritableReg (temp_writable_reg ty)) 2627 (_ Unit (emit (MInst.VecLoadElt32Rev dst addr)))) 2628 dst)) 2629 2630;; Helper for emitting `MInst.VecLoadElt64Rev` instructions. 2631(decl vec_load_elt64rev (Type MemArg) Reg) 2632(rule (vec_load_elt64rev ty addr) 2633 (let ((dst WritableReg (temp_writable_reg ty)) 2634 (_ Unit (emit (MInst.VecLoadElt64Rev dst addr)))) 2635 dst)) 2636 2637;; Helper for emitting `MInst.VecStore` instructions. 2638(decl vec_store (Reg MemArg) SideEffectNoResult) 2639(rule (vec_store src addr) 2640 (SideEffectNoResult.Inst (MInst.VecStore src addr))) 2641 2642;; Helper for emitting `MInst.VecStoreRev` instructions. 2643(decl vec_storerev (Reg MemArg) SideEffectNoResult) 2644(rule (vec_storerev src addr) 2645 (SideEffectNoResult.Inst (MInst.VecStoreRev src addr))) 2646 2647;; Helper for emitting `MInst.VecStoreByte16Rev` instructions. 2648(decl vec_store_byte16rev (Reg MemArg) SideEffectNoResult) 2649(rule (vec_store_byte16rev src addr) 2650 (SideEffectNoResult.Inst (MInst.VecStoreByte16Rev src addr))) 2651 2652;; Helper for emitting `MInst.VecStoreByte32Rev` instructions. 2653(decl vec_store_byte32rev (Reg MemArg) SideEffectNoResult) 2654(rule (vec_store_byte32rev src addr) 2655 (SideEffectNoResult.Inst (MInst.VecStoreByte32Rev src addr))) 2656 2657;; Helper for emitting `MInst.VecStoreByte64Rev` instructions. 2658(decl vec_store_byte64rev (Reg MemArg) SideEffectNoResult) 2659(rule (vec_store_byte64rev src addr) 2660 (SideEffectNoResult.Inst (MInst.VecStoreByte64Rev src addr))) 2661 2662;; Helper for emitting `MInst.VecStoreElt16Rev` instructions. 2663(decl vec_store_elt16rev (Reg MemArg) SideEffectNoResult) 2664(rule (vec_store_elt16rev src addr) 2665 (SideEffectNoResult.Inst (MInst.VecStoreElt16Rev src addr))) 2666 2667;; Helper for emitting `MInst.VecStoreElt32Rev` instructions. 2668(decl vec_store_elt32rev (Reg MemArg) SideEffectNoResult) 2669(rule (vec_store_elt32rev src addr) 2670 (SideEffectNoResult.Inst (MInst.VecStoreElt32Rev src addr))) 2671 2672;; Helper for emitting `MInst.VecStoreElt64Rev` instructions. 2673(decl vec_store_elt64rev (Reg MemArg) SideEffectNoResult) 2674(rule (vec_store_elt64rev src addr) 2675 (SideEffectNoResult.Inst (MInst.VecStoreElt64Rev src addr))) 2676 2677;; Helper for emitting `MInst.VecLoadReplicate` instructions. 2678(decl vec_load_replicate (Type MemArg) Reg) 2679(rule (vec_load_replicate (ty_vec128 ty @ (multi_lane size _)) addr) 2680 (let ((dst WritableReg (temp_writable_reg ty)) 2681 (_ Unit (emit (MInst.VecLoadReplicate size dst addr)))) 2682 dst)) 2683 2684;; Helper for emitting `MInst.VecLoadReplicateRev` instructions. 2685(decl vec_load_replicate_rev (Type MemArg) Reg) 2686(rule (vec_load_replicate_rev (ty_vec128 ty @ (multi_lane size _)) addr) 2687 (let ((dst WritableReg (temp_writable_reg ty)) 2688 (_ Unit (emit (MInst.VecLoadReplicateRev size dst addr)))) 2689 dst)) 2690 2691;; Helper for emitting `MInst.MovToVec128` instructions. 2692(decl mov_to_vec128 (Type Reg Reg) Reg) 2693(rule (mov_to_vec128 ty src1 src2) 2694 (let ((dst WritableReg (temp_writable_reg ty)) 2695 (_ Unit (emit (MInst.MovToVec128 dst src1 src2)))) 2696 dst)) 2697 2698;; Helper for emitting `MInst.VecImmByteMask` instructions. 2699(decl vec_imm_byte_mask (Type u16) Reg) 2700(rule (vec_imm_byte_mask (vr128_ty ty) n) 2701 (let ((dst WritableReg (temp_writable_reg ty)) 2702 (_ Unit (emit (MInst.VecImmByteMask dst n)))) 2703 dst)) 2704 2705;; Helper for emitting `MInst.VecImmBitMask` instructions. 2706(decl vec_imm_bit_mask (Type u8 u8) Reg) 2707(rule (vec_imm_bit_mask (ty_vec128 ty @ (multi_lane size _)) start_bit end_bit) 2708 (let ((dst WritableReg (temp_writable_reg ty)) 2709 (_ Unit (emit (MInst.VecImmBitMask size dst start_bit end_bit)))) 2710 dst)) 2711 2712;; Helper for emitting `MInst.VecImmReplicate` instructions. 2713(decl vec_imm_replicate (Type i16) Reg) 2714(rule (vec_imm_replicate (ty_vec128 ty @ (multi_lane size _)) n) 2715 (let ((dst WritableReg (temp_writable_reg ty)) 2716 (_ Unit (emit (MInst.VecImmReplicate size dst n)))) 2717 dst)) 2718 2719;; Helper for emitting `MInst.VecLoadLane` instructions. 2720(decl vec_load_lane (Type Reg MemArg u8) Reg) 2721(rule (vec_load_lane ty @ (multi_lane size _) src addr lane_imm) 2722 (let ((dst WritableReg (temp_writable_reg ty)) 2723 (_ Unit (emit (MInst.VecLoadLane size dst src addr lane_imm)))) 2724 dst)) 2725 2726;; Helper for emitting `MInst.VecLoadLaneUndef` instructions. 2727(decl vec_load_lane_undef (Type MemArg u8) Reg) 2728(rule (vec_load_lane_undef ty @ (multi_lane size _) addr lane_imm) 2729 (let ((dst WritableReg (temp_writable_reg ty)) 2730 (_ Unit (emit (MInst.VecLoadLaneUndef size dst addr lane_imm)))) 2731 dst)) 2732 2733;; Helper for emitting `MInst.VecLoadLaneRev` instructions. 2734(decl vec_load_lane_rev (Type Reg MemArg u8) Reg) 2735(rule (vec_load_lane_rev ty @ (multi_lane size _) src addr lane_imm) 2736 (let ((dst WritableReg (temp_writable_reg ty)) 2737 (_ Unit (emit (MInst.VecLoadLaneRev size dst src addr lane_imm)))) 2738 dst)) 2739 2740;; Helper for emitting `MInst.VecLoadLaneRevUndef` instructions. 2741(decl vec_load_lane_rev_undef (Type MemArg u8) Reg) 2742(rule (vec_load_lane_rev_undef ty @ (multi_lane size _) addr lane_imm) 2743 (let ((dst WritableReg (temp_writable_reg ty)) 2744 (_ Unit (emit (MInst.VecLoadLaneRevUndef size dst addr lane_imm)))) 2745 dst)) 2746 2747;; Helper for emitting `MInst.VecStoreLane` instructions. 2748(decl vec_store_lane (Type Reg MemArg u8) SideEffectNoResult) 2749(rule (vec_store_lane ty @ (multi_lane size _) src addr lane_imm) 2750 (SideEffectNoResult.Inst (MInst.VecStoreLane size src addr lane_imm))) 2751 2752;; Helper for emitting `MInst.VecStoreLaneRev` instructions. 2753(decl vec_store_lane_rev (Type Reg MemArg u8) SideEffectNoResult) 2754(rule (vec_store_lane_rev ty @ (multi_lane size _) src addr lane_imm) 2755 (SideEffectNoResult.Inst (MInst.VecStoreLaneRev size src addr lane_imm))) 2756 2757;; Helper for emitting `MInst.VecInsertLane` instructions. 2758(decl vec_insert_lane (Type Reg Reg u8 Reg) Reg) 2759(rule (vec_insert_lane ty @ (multi_lane size _) src1 src2 lane_imm lane_reg) 2760 (let ((dst WritableReg (temp_writable_reg ty)) 2761 (_ Unit (emit (MInst.VecInsertLane size dst src1 src2 lane_imm lane_reg)))) 2762 dst)) 2763 2764;; Helper for emitting `MInst.VecInsertLaneUndef` instructions. 2765(decl vec_insert_lane_undef (Type Reg u8 Reg) Reg) 2766(rule (vec_insert_lane_undef ty @ (multi_lane size _) src lane_imm lane_reg) 2767 (let ((dst WritableReg (temp_writable_reg ty)) 2768 (_ Unit (emit (MInst.VecInsertLaneUndef size dst src lane_imm lane_reg)))) 2769 dst)) 2770 2771;; Helper for emitting `MInst.VecExtractLane` instructions. 2772(decl vec_extract_lane (Type Reg u8 Reg) Reg) 2773(rule (vec_extract_lane (multi_lane size _) src lane_imm lane_reg) 2774 (let ((dst WritableReg (temp_writable_reg $I64)) 2775 (_ Unit (emit (MInst.VecExtractLane size dst src lane_imm lane_reg)))) 2776 dst)) 2777 2778;; Helper for emitting `MInst.VecInsertLaneImm` instructions. 2779(decl vec_insert_lane_imm (Type Reg i16 u8) Reg) 2780(rule (vec_insert_lane_imm ty @ (multi_lane size _) src imm lane_imm) 2781 (let ((dst WritableReg (temp_writable_reg ty)) 2782 (_ Unit (emit (MInst.VecInsertLaneImm size dst src imm lane_imm)))) 2783 dst)) 2784 2785;; Helper for emitting `MInst.VecInsertLaneImmUndef` instructions. 2786(decl vec_insert_lane_imm_undef (Type i16 u8) Reg) 2787(rule (vec_insert_lane_imm_undef ty @ (multi_lane size _) imm lane_imm) 2788 (let ((dst WritableReg (temp_writable_reg ty)) 2789 (_ Unit (emit (MInst.VecInsertLaneImmUndef size dst imm lane_imm)))) 2790 dst)) 2791 2792;; Helper for emitting `MInst.VecReplicateLane` instructions. 2793(decl vec_replicate_lane (Type Reg u8) Reg) 2794(rule (vec_replicate_lane ty @ (multi_lane size _) src lane_imm) 2795 (let ((dst WritableReg (temp_writable_reg ty)) 2796 (_ Unit (emit (MInst.VecReplicateLane size dst src lane_imm)))) 2797 dst)) 2798 2799;; Helper for emitting `MInst.VecEltRev` instructions. 2800(decl vec_elt_rev (Type Reg) Reg) 2801(rule (vec_elt_rev ty @ (multi_lane _ lanes) src) 2802 (let ((dst WritableReg (temp_writable_reg ty)) 2803 (_ Unit (emit (MInst.VecEltRev lanes dst src)))) 2804 dst)) 2805 2806;; Helper for emitting `MInst.LoadSymbolReloc` instructions. 2807(decl load_symbol_reloc (SymbolReloc) Reg) 2808(rule (load_symbol_reloc symbol_reloc) 2809 (let ((dst WritableReg (temp_writable_reg $I64)) 2810 (_ Unit (emit (MInst.LoadSymbolReloc dst symbol_reloc)))) 2811 dst)) 2812 2813;; Helper for emitting `MInst.LoadAddr` instructions. 2814(decl load_addr (MemArg) Reg) 2815(rule (load_addr mem) 2816 (let ((dst WritableReg (temp_writable_reg $I64)) 2817 (_ Unit (emit (MInst.LoadAddr dst mem)))) 2818 dst)) 2819 2820;; Helper for emitting `MInst.Call` instructions. 2821(decl call_impl (WritableReg BoxCallInfo) SideEffectNoResult) 2822(rule (call_impl reg info) 2823 (SideEffectNoResult.Inst (MInst.Call reg info))) 2824 2825;; Helper for emitting `MInst.ReturnCall` instructions. 2826(decl return_call_impl (BoxReturnCallInfo) SideEffectNoResult) 2827(rule (return_call_impl info) 2828 (SideEffectNoResult.Inst (MInst.ReturnCall info))) 2829 2830;; Helper for emitting `MInst.Jump` instructions. 2831(decl jump_impl (MachLabel) SideEffectNoResult) 2832(rule (jump_impl target) 2833 (SideEffectNoResult.Inst (MInst.Jump target))) 2834 2835;; Helper for emitting `MInst.CondBr` instructions. 2836(decl cond_br (MachLabel MachLabel Cond) ConsumesFlags) 2837(rule (cond_br taken not_taken cond) 2838 (ConsumesFlags.ConsumesFlagsSideEffect (MInst.CondBr taken not_taken cond))) 2839 2840;; Helper for emitting `MInst.JTSequence` instructions. 2841(decl jt_sequence (Reg MachLabel Cond BoxVecMachLabel) ConsumesFlags) 2842(rule (jt_sequence ridx default default_cond targets) 2843 (ConsumesFlags.ConsumesFlagsSideEffect (MInst.JTSequence ridx default default_cond targets))) 2844 2845;; Emit a jump-table sequence based on a boolean condition for the 2846;; default label. 2847(decl jt_sequence_default_bool (Reg MachLabel ProducesBool BoxVecMachLabel) SideEffectNoResult) 2848(rule (jt_sequence_default_bool ridx default (ProducesBool.ProducesBool default_producer default_cond) targets) 2849 (with_flags_side_effect 2850 default_producer 2851 (jt_sequence ridx default default_cond targets))) 2852 2853;; Helpers for instruction sequences ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2854 2855;; Completed instruction sequence for use in MInst.Loop. 2856(type VecMInst (primitive VecMInst)) 2857 2858;; Partial (mutable) instruction sequence in the process of being created. 2859(type VecMInstBuilder extern (enum)) 2860 2861;; Create a new empty instruction sequence builder. 2862(decl inst_builder_new () VecMInstBuilder) 2863(extern constructor inst_builder_new inst_builder_new) 2864 2865;; Push an instruction to a sequence under construction. 2866(decl inst_builder_push (VecMInstBuilder MInst) Unit) 2867(extern constructor inst_builder_push inst_builder_push) 2868 2869;; Complete the sequence under construction. 2870(decl inst_builder_finish (VecMInstBuilder) VecMInst) 2871(extern constructor inst_builder_finish inst_builder_finish) 2872 2873;; It is not safe to write to virtual registers in the loop, so all destination 2874;; registers must be real. This must be handled by the user of these helpers, 2875;; so we simply verify this constraint here. 2876(decl real_reg (WritableReg) WritableReg) 2877(extern extractor real_reg real_reg) 2878 2879;; Similarly, because we cannot allocate temp registers, if an instruction 2880;; requires matching source and destination registers, this needs to be handled 2881;; by the user. Another helper to verify that constraint. 2882(decl pure partial same_reg (WritableReg Reg) Reg) 2883(extern constructor same_reg same_reg) 2884 2885;; Push a `MInst.AluRRR` instruction to a sequence. 2886(decl push_alu_reg (VecMInstBuilder ALUOp WritableReg Reg Reg) Reg) 2887(rule (push_alu_reg ib op (real_reg dst) src1 src2) 2888 (let ((_ Unit (inst_builder_push ib (MInst.AluRRR op dst src1 src2)))) 2889 dst)) 2890 2891;; Push a `MInst.AluRUImm32Shifted` instruction to a sequence. 2892(decl push_alu_uimm32shifted (VecMInstBuilder ALUOp WritableReg Reg UImm32Shifted) Reg) 2893(rule (push_alu_uimm32shifted ib op (real_reg dst) r imm) 2894 (let ((_ Unit (inst_builder_push ib (MInst.AluRUImm32Shifted op dst r imm)))) 2895 dst)) 2896 2897;; Push a `MInst.ShiftRR` instruction to a sequence. 2898(decl push_shift (VecMInstBuilder ShiftOp WritableReg Reg u8 Reg) Reg) 2899(rule (push_shift ib op (real_reg dst) src shift_imm shift_reg) 2900 (let ((_ Unit (inst_builder_push ib 2901 (MInst.ShiftRR op dst src shift_imm shift_reg)))) 2902 dst)) 2903 2904;; Push a `MInst.RxSBG` instruction to a sequence. 2905(decl push_rxsbg (VecMInstBuilder RxSBGOp WritableReg Reg Reg u8 u8 i8) Reg) 2906(rule (push_rxsbg ib op (real_reg dst) r src start_bit end_bit rotate_amt) 2907 (if (same_reg dst r)) 2908 (let ((_ Unit (inst_builder_push ib 2909 (MInst.RxSBG op dst r src start_bit end_bit rotate_amt)))) 2910 dst)) 2911 2912;; Push a `MInst.UnaryRR` instruction to a sequence. 2913(decl push_unary (VecMInstBuilder UnaryOp WritableReg Reg) Reg) 2914(rule (push_unary ib op (real_reg dst) src) 2915 (let ((_ Unit (inst_builder_push ib (MInst.UnaryRR op dst src)))) 2916 dst)) 2917 2918;; Push a `MInst.AtomicCas32` instruction to a sequence. 2919(decl push_atomic_cas32 (VecMInstBuilder WritableReg Reg MemArg) Reg) 2920(rule (push_atomic_cas32 ib (real_reg dst_src1) src2 mem) 2921 (let ((_ Unit (inst_builder_push ib (MInst.AtomicCas32 dst_src1 dst_src1 src2 mem)))) 2922 dst_src1)) 2923 2924;; Push a `MInst.AtomicCas64` instruction to a sequence. 2925(decl push_atomic_cas64 (VecMInstBuilder WritableReg Reg MemArg) Reg) 2926(rule (push_atomic_cas64 ib (real_reg dst_src1) src2 mem) 2927 (let ((_ Unit (inst_builder_push ib (MInst.AtomicCas64 dst_src1 dst_src1 src2 mem)))) 2928 dst_src1)) 2929 2930;; Push instructions to break out of the loop if condition is met. 2931(decl push_break_if (VecMInstBuilder ProducesFlags Cond) Reg) 2932(rule (push_break_if ib (ProducesFlags.ProducesFlagsSideEffect inst) cond) 2933 (let ((_ Unit (inst_builder_push ib inst)) 2934 (_ Unit (inst_builder_push ib (MInst.CondBreak cond)))) 2935 (invalid_reg))) 2936 2937;; Emit a `MInst.Loop` instruction holding a loop body instruction sequence. 2938(decl emit_loop (VecMInstBuilder Cond) Unit) 2939(rule (emit_loop ib cond) 2940 (emit (MInst.Loop (inst_builder_finish ib) cond))) 2941 2942 2943;; Helpers for generating register moves ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2944 2945;; Copy GPR into a virtual register. 2946(decl copy_reg (Type Reg) Reg) 2947(rule 1 (copy_reg (gpr32_ty ty) src) 2948 (let ((dst WritableReg (temp_writable_reg ty)) 2949 (_ Unit (emit (MInst.Mov32 dst src)))) 2950 dst)) 2951(rule 2 (copy_reg (gpr64_ty ty) src) 2952 (let ((dst WritableReg (temp_writable_reg ty)) 2953 (_ Unit (emit (MInst.Mov64 dst src)))) 2954 dst)) 2955 2956;; Move from memory location into destination. 2957(decl emit_load (Type WritableReg MemArg) Unit) 2958(rule (emit_load $I32 dst addr) 2959 (emit (MInst.Load32 dst addr))) 2960(rule (emit_load $I64 dst addr) 2961 (emit (MInst.Load64 dst addr))) 2962 2963;; Helper for creating `MInst.MovPReg` instructions. 2964(decl mov_preg (PReg) Reg) 2965(rule (mov_preg src) 2966 (let ((dst WritableReg (temp_writable_reg $I64)) 2967 (_ Unit (emit (MInst.MovPReg dst src)))) 2968 dst)) 2969 2970(decl preg_stack () PReg) 2971(extern constructor preg_stack preg_stack) 2972 2973(decl preg_gpr_0 () PReg) 2974(extern constructor preg_gpr_0 preg_gpr_0) 2975 2976;; Copy the physical stack register into a virtual register. 2977(decl sp () Reg) 2978(rule (sp) 2979 (mov_preg (preg_stack))) 2980 2981 2982;; Helpers for generating immediate values ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 2983 2984;; Allocate a temporary register, initialized with an immediate. 2985(decl rec imm (Type u64) Reg) 2986 2987;; 16-bit (or smaller) result type, any value 2988(rule 7 (imm (fits_in_16 (ty_int ty)) n) 2989 (let ((dst WritableReg (temp_writable_reg ty)) 2990 (_ Unit (emit (MInst.Mov32SImm16 dst (u16_cast_signed (u64_truncate_into_u16 n)))))) 2991 dst)) 2992 2993;; 32-bit result type, value fits in i16 2994(rule 6 (imm (gpr32_ty ty) (u32_pair _ m)) 2995 (if-let (i16_from_i32 n) (u32_cast_signed m)) 2996 (let ((dst WritableReg (temp_writable_reg ty)) 2997 (_ Unit (emit (MInst.Mov32SImm16 dst n)))) 2998 dst)) 2999 3000;; 32-bit result type, any value 3001(rule 5 (imm (gpr32_ty ty) n) 3002 (let ((dst WritableReg (temp_writable_reg ty)) 3003 (_ Unit (emit (MInst.Mov32Imm dst (u64_truncate_into_u32 n))))) 3004 dst)) 3005 3006;; 64-bit result type, value fits in i16 3007(rule 4 (imm (gpr64_ty ty) m) 3008 (if-let (i16_from_i64 n) (u64_cast_signed m)) 3009 (let ((dst WritableReg (temp_writable_reg ty)) 3010 (_ Unit (emit (MInst.Mov64SImm16 dst n)))) 3011 dst)) 3012 3013;; 64-bit result type, value fits in i32 3014(rule 3 (imm (gpr64_ty ty) m) 3015 (if-let (i32_from_i64 n) (u64_cast_signed m)) 3016 (let ((dst WritableReg (temp_writable_reg ty)) 3017 (_ Unit (emit (MInst.Mov64SImm32 dst n)))) 3018 dst)) 3019 3020;; 64-bit result type, value fits in UImm16Shifted 3021(rule 2 (imm (gpr64_ty ty) (uimm16shifted_from_u64 n)) 3022 (let ((dst WritableReg (temp_writable_reg ty)) 3023 (_ Unit (emit (MInst.Mov64UImm16Shifted dst n)))) 3024 dst)) 3025 3026;; 64-bit result type, value fits in UImm32Shifted 3027(rule 1 (imm (gpr64_ty ty) (uimm32shifted_from_u64 n)) 3028 (let ((dst WritableReg (temp_writable_reg ty)) 3029 (_ Unit (emit (MInst.Mov64UImm32Shifted dst n)))) 3030 dst)) 3031 3032;; 64-bit result type, value with non-zero low-/high-parts. 3033(rule 0 (imm (gpr64_ty ty) (and (u64_nonzero_hipart hi) 3034 (u64_nonzero_lopart lo))) 3035 (insert_imm ty (imm ty hi) lo)) 3036 3037;; Replace low 32 bits of 64-bit value with immediate. 3038(decl insert_imm (Type Reg u64) Reg) 3039 3040;; Insertion, value fits in UImm16Shifted 3041(rule 1 (insert_imm ty src (uimm16shifted_from_u64 n)) 3042 (let ((dst WritableReg (temp_writable_reg ty)) 3043 (_ Unit (emit (MInst.Insert64UImm16Shifted dst src n)))) 3044 dst)) 3045 3046;; Insertion, value fits in UImm32Shifted 3047(rule (insert_imm ty src (uimm32shifted_from_u64 n)) 3048 (let ((dst WritableReg (temp_writable_reg ty)) 3049 (_ Unit (emit (MInst.Insert64UImm32Shifted dst src n)))) 3050 dst)) 3051 3052;; 16-bit floating-point type, any value. 3053(rule 8 (imm $F16 n) 3054 (vec_insert_lane_imm_undef $F16X8 3055 (u16_cast_signed (u64_truncate_into_u16 n)) 3056 0)) 3057 3058;; 32-bit floating-point type, any value. Loaded from literal pool. 3059;; FIXME: This wastes 4 bytes of constant pool space. 3060;; TODO: use LZER to load 0.0 3061(rule 8 (imm $F32 n) 3062 (vec_load_lane_undef $F32X4 3063 (memarg_const (emit_u64_be_const (u32_pair (u64_truncate_into_u32 n) 0))) 0)) 3064 3065;; 64-bit floating-point type, any value. Loaded from literal pool. 3066;; TODO: use LZDR to load 0.0 3067(rule 8 (imm $F64 n) 3068 (vec_load_lane_undef $F64X2 (memarg_const (emit_u64_be_const n)) 0)) 3069 3070;; Variant used for negative constants. 3071(decl imm32 (Type i32) Reg) 3072(rule (imm32 $I64 n) 3073 (let ((dst WritableReg (temp_writable_reg $I64)) 3074 (_ Unit (emit (MInst.Mov64SImm32 dst n)))) 3075 (writable_reg_to_reg dst))) 3076 3077;; Allocate a temporary register, initialized with a vector immediate. 3078(decl vec_imm (Type u128) Reg) 3079(rule 2 (vec_imm (vr128_ty ty) 0) 3080 (vec_imm_byte_mask ty 0)) 3081(rule 1 (vec_imm (vr128_ty ty) (u64_pair n n)) 3082 (vec_imm_splat $I64X2 n)) 3083(rule (vec_imm (vr128_ty ty) n) 3084 (vec_load ty (memarg_const (emit_u128_be_const n)))) 3085 3086;; Variant with replicated immediate. 3087;; 3088;; Recursion: bounded since recursive rules reduce number of lanes. 3089(decl rec vec_imm_splat (Type u64) Reg) 3090(rule 1 (vec_imm_splat (ty_vec128 ty) 0) 3091 (vec_imm_byte_mask ty 0)) 3092(rule 2 (vec_imm_splat ty @ (multi_lane 8 _) n) 3093 (vec_imm_replicate ty (u16_cast_signed (u64_truncate_into_u16 n)))) 3094(rule 2 (vec_imm_splat ty @ (multi_lane 16 _) n) 3095 (vec_imm_replicate ty (u16_cast_signed (u64_truncate_into_u16 n)))) 3096(rule 2 (vec_imm_splat ty @ (multi_lane 32 _) (u32_pair _ m)) 3097 (if-let (i16_from_i32 n) (u32_cast_signed m)) 3098 (vec_imm_replicate ty n)) 3099(rule 2 (vec_imm_splat ty @ (multi_lane 64 _) m) 3100 (if-let (i16_from_i64 n) (u64_cast_signed m)) 3101 (vec_imm_replicate ty n)) 3102(rule 3 (vec_imm_splat (multi_lane 16 _) (u32_pair _ (u16_pair _ (u8_pair n n)))) 3103 (vec_imm_splat $I8X16 n)) 3104(rule 3 (vec_imm_splat (multi_lane 32 _) (u32_pair _ (u16_pair n n))) 3105 (vec_imm_splat $I16X8 n)) 3106(rule 3 (vec_imm_splat (multi_lane 64 _) (u32_pair n n)) 3107 (vec_imm_splat $I32X4 n)) 3108;; FIXME: This wastes 4 bytes of constant pool space. 3109(rule 0 (vec_imm_splat ty @ (multi_lane 32 _) n) 3110 (vec_load_replicate ty 3111 (memarg_const (emit_u64_be_const (u32_pair (u64_truncate_into_u32 n) 0))))) 3112(rule 0 (vec_imm_splat ty @ (multi_lane 64 _) n) 3113 (vec_load_replicate ty (memarg_const (emit_u64_be_const n)))) 3114 3115;; Helpers for generating extensions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3116 3117;; Result type of extending integer `Type` to 32 bits if smaller. 3118(decl ty_ext32 (Type) Type) 3119(rule (ty_ext32 $I8) $I32) 3120(rule (ty_ext32 $I16) $I32) 3121(rule (ty_ext32 $I32) $I32) 3122(rule (ty_ext32 $I64) $I64) 3123 3124;; Result type of extending integer `Type` to 64 bits if smaller. 3125(decl ty_ext64 (Type) Type) 3126(rule (ty_ext64 $I8) $I64) 3127(rule (ty_ext64 $I16) $I64) 3128(rule (ty_ext64 $I32) $I64) 3129(rule (ty_ext64 $I64) $I64) 3130 3131 3132;; Zero-extend a register from a smaller `Type` into a 32-bit register. 3133(decl zext32_reg (Type Reg) Reg) 3134(rule (zext32_reg ty src) 3135 (let ((dst WritableReg (temp_writable_reg $I32)) 3136 (_ Unit (emit (MInst.Extend dst src false (ty_bits ty) 32)))) 3137 dst)) 3138 3139;; Sign-extend a register from a smaller `Type` into a 32-bit register. 3140(decl sext32_reg (Type Reg) Reg) 3141(rule (sext32_reg ty src) 3142 (let ((dst WritableReg (temp_writable_reg $I32)) 3143 (_ Unit (emit (MInst.Extend dst src true (ty_bits ty) 32)))) 3144 dst)) 3145 3146;; Zero-extend a register from a smaller `Type` into a 64-bit register. 3147(decl zext64_reg (Type Reg) Reg) 3148(rule (zext64_reg ty src) 3149 (let ((dst WritableReg (temp_writable_reg $I64)) 3150 (_ Unit (emit (MInst.Extend dst src false (ty_bits ty) 64)))) 3151 dst)) 3152 3153;; Sign-extend a register from a smaller `Type` into a 64-bit register. 3154(decl sext64_reg (Type Reg) Reg) 3155(rule (sext64_reg ty src) 3156 (let ((dst WritableReg (temp_writable_reg $I64)) 3157 (_ Unit (emit (MInst.Extend dst src true (ty_bits ty) 64)))) 3158 dst)) 3159 3160 3161;; Zero-extend memory from a smaller `Type` into a 32-bit register. 3162(decl zext32_mem (Type MemArg) Reg) 3163(rule (zext32_mem $I8 mem) 3164 (let ((dst WritableReg (temp_writable_reg $I32)) 3165 (_ Unit (emit (MInst.Load32ZExt8 dst mem)))) 3166 dst)) 3167(rule (zext32_mem $I16 mem) 3168 (let ((dst WritableReg (temp_writable_reg $I32)) 3169 (_ Unit (emit (MInst.Load32ZExt16 dst mem)))) 3170 dst)) 3171 3172;; Sign-extend memory from a smaller `Type` into a 32-bit register. 3173(decl sext32_mem (Type MemArg) Reg) 3174(rule (sext32_mem $I8 mem) 3175 (let ((dst WritableReg (temp_writable_reg $I32)) 3176 (_ Unit (emit (MInst.Load32SExt8 dst mem)))) 3177 dst)) 3178(rule (sext32_mem $I16 mem) 3179 (let ((dst WritableReg (temp_writable_reg $I32)) 3180 (_ Unit (emit (MInst.Load32SExt16 dst mem)))) 3181 dst)) 3182 3183;; Zero-extend memory from a smaller `Type` into a 64-bit register. 3184(decl zext64_mem (Type MemArg) Reg) 3185(rule (zext64_mem $I8 mem) 3186 (let ((dst WritableReg (temp_writable_reg $I64)) 3187 (_ Unit (emit (MInst.Load64ZExt8 dst mem)))) 3188 dst)) 3189(rule (zext64_mem $I16 mem) 3190 (let ((dst WritableReg (temp_writable_reg $I64)) 3191 (_ Unit (emit (MInst.Load64ZExt16 dst mem)))) 3192 dst)) 3193(rule (zext64_mem $I32 mem) 3194 (let ((dst WritableReg (temp_writable_reg $I64)) 3195 (_ Unit (emit (MInst.Load64ZExt32 dst mem)))) 3196 dst)) 3197 3198;; Sign-extend memory from a smaller `Type` into a 64-bit register. 3199(decl sext64_mem (Type MemArg) Reg) 3200(rule (sext64_mem $I8 mem) 3201 (let ((dst WritableReg (temp_writable_reg $I64)) 3202 (_ Unit (emit (MInst.Load64SExt8 dst mem)))) 3203 dst)) 3204(rule (sext64_mem $I16 mem) 3205 (let ((dst WritableReg (temp_writable_reg $I64)) 3206 (_ Unit (emit (MInst.Load64SExt16 dst mem)))) 3207 dst)) 3208(rule (sext64_mem $I32 mem) 3209 (let ((dst WritableReg (temp_writable_reg $I64)) 3210 (_ Unit (emit (MInst.Load64SExt32 dst mem)))) 3211 dst)) 3212 3213 3214;; Place `Value` into a register, zero-extending to 32 bits if smaller. 3215(decl put_in_reg_zext32 (Value) Reg) 3216(rule 3 (put_in_reg_zext32 (and (value_type ty) (u64_from_value val))) 3217 (imm (ty_ext32 ty) val)) 3218(rule 1 (put_in_reg_zext32 (and (value_type (fits_in_16 ty)) (sinkable_load load))) 3219 (zext32_mem ty (sink_load load))) 3220(rule 0 (put_in_reg_zext32 val @ (value_type (fits_in_16 ty))) 3221 (zext32_reg ty val)) 3222(rule 2 (put_in_reg_zext32 val @ (value_type (ty_32_or_64 _ty))) 3223 val) 3224 3225;; Place `Value` into a register, sign-extending to 32 bits if smaller. 3226(decl put_in_reg_sext32 (Value) Reg) 3227(rule 3 (put_in_reg_sext32 (and (value_type ty) (u64_from_signed_value val))) 3228 (imm (ty_ext32 ty) val)) 3229(rule 1 (put_in_reg_sext32 (and (value_type (fits_in_16 ty)) (sinkable_load load))) 3230 (sext32_mem ty (sink_load load))) 3231(rule 0 (put_in_reg_sext32 val @ (value_type (fits_in_16 ty))) 3232 (sext32_reg ty val)) 3233(rule 2 (put_in_reg_sext32 val @ (value_type (ty_32_or_64 _ty))) 3234 val) 3235 3236;; Place `Value` into a register, zero-extending to 64 bits if smaller. 3237(decl put_in_reg_zext64 (Value) Reg) 3238(rule 3 (put_in_reg_zext64 (and (value_type ty) (u64_from_value val))) 3239 (imm (ty_ext64 ty) val)) 3240(rule 1 (put_in_reg_zext64 (and (value_type (gpr32_ty ty)) (sinkable_load load))) 3241 (zext64_mem ty (sink_load load))) 3242(rule 0 (put_in_reg_zext64 val @ (value_type (gpr32_ty ty))) 3243 (zext64_reg ty val)) 3244(rule 2 (put_in_reg_zext64 val @ (value_type (gpr64_ty ty))) 3245 val) 3246 3247;; Place `Value` into a register, sign-extending to 64 bits if smaller. 3248(decl put_in_reg_sext64 (Value) Reg) 3249(rule 3 (put_in_reg_sext64 (and (value_type ty) (u64_from_signed_value val))) 3250 (imm (ty_ext64 ty) val)) 3251(rule 1 (put_in_reg_sext64 (and (value_type (gpr32_ty ty)) (sinkable_load load))) 3252 (sext64_mem ty (sink_load load))) 3253(rule 0 (put_in_reg_sext64 val @ (value_type (gpr32_ty ty))) 3254 (sext64_reg ty val)) 3255(rule 2 (put_in_reg_sext64 val @ (value_type (gpr64_ty ty))) 3256 val) 3257 3258 3259;; Helpers for generating conditional moves ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3260 3261;; Conditionally select between immediate and source register. 3262(decl cmov_imm (Type Cond i16 Reg) ConsumesFlags) 3263(rule 0 (cmov_imm (gpr32_ty ty) cond imm_true reg_false) 3264 (let ((dst WritableReg (temp_writable_reg ty)) 3265 (inst MInst (MInst.CMov32SImm16 dst cond reg_false imm_true))) 3266 (ConsumesFlags.ConsumesFlagsReturnsReg inst dst))) 3267(rule 1 (cmov_imm (gpr64_ty ty) cond imm_true reg_false) 3268 (let ((dst WritableReg (temp_writable_reg ty)) 3269 (inst MInst (MInst.CMov64SImm16 dst cond reg_false imm_true))) 3270 (ConsumesFlags.ConsumesFlagsReturnsReg inst dst))) 3271 3272;; Conditionally select between two immediates. 3273(decl cmov_imm_imm (Type Cond i16 i16) ConsumesFlags) 3274(rule 0 (cmov_imm_imm (gpr32_ty ty) cond imm_true imm_false) 3275 (let ((tmp1 WritableReg (temp_writable_reg ty)) 3276 (tmp2 WritableReg (temp_writable_reg ty)) 3277 (inst1 MInst (MInst.Mov32SImm16 tmp1 imm_false)) 3278 (inst2 MInst (MInst.CMov32SImm16 tmp2 cond tmp1 imm_true)) 3279 (dst ValueRegs (value_reg tmp2))) 3280 (ConsumesFlags.ConsumesFlagsTwiceReturnsValueRegs inst1 inst2 dst))) 3281(rule 1 (cmov_imm_imm (gpr64_ty ty) cond imm_true imm_false) 3282 (let ((tmp1 WritableReg (temp_writable_reg ty)) 3283 (tmp2 WritableReg (temp_writable_reg ty)) 3284 (inst1 MInst (MInst.Mov64SImm16 tmp1 imm_false)) 3285 (inst2 MInst (MInst.CMov64SImm16 tmp2 cond tmp1 imm_true)) 3286 (dst ValueRegs (value_reg tmp2))) 3287 (ConsumesFlags.ConsumesFlagsTwiceReturnsValueRegs inst1 inst2 dst))) 3288 3289;; Conditionally select between two source registers. 3290(decl cmov_reg_reg (Type Cond Reg Reg) ConsumesFlags) 3291(rule 1 (cmov_reg_reg (gpr32_ty ty) cond reg_true reg_false) 3292 (let ((dst WritableReg (temp_writable_reg ty)) 3293 (inst MInst (MInst.CMov32 dst cond reg_false reg_true))) 3294 (ConsumesFlags.ConsumesFlagsReturnsReg inst dst))) 3295(rule 2 (cmov_reg_reg (gpr64_ty ty) cond reg_true reg_false) 3296 (let ((dst WritableReg (temp_writable_reg ty)) 3297 (inst MInst (MInst.CMov64 dst cond reg_false reg_true))) 3298 (ConsumesFlags.ConsumesFlagsReturnsReg inst dst))) 3299(rule 3 (cmov_reg_reg $F16 cond reg_true reg_false) 3300 (let ((dst WritableReg (temp_writable_reg $F16)) 3301 (inst MInst (MInst.FpuCMov32 dst cond reg_false reg_true))) 3302 (ConsumesFlags.ConsumesFlagsReturnsReg inst dst))) 3303(rule 3 (cmov_reg_reg $F32 cond reg_true reg_false) 3304 (let ((dst WritableReg (temp_writable_reg $F32)) 3305 (inst MInst (MInst.FpuCMov32 dst cond reg_false reg_true))) 3306 (ConsumesFlags.ConsumesFlagsReturnsReg inst dst))) 3307(rule 3 (cmov_reg_reg $F64 cond reg_true reg_false) 3308 (let ((dst WritableReg (temp_writable_reg $F64)) 3309 (inst MInst (MInst.FpuCMov64 dst cond reg_false reg_true))) 3310 (ConsumesFlags.ConsumesFlagsReturnsReg inst dst))) 3311(rule 0 (cmov_reg_reg (vr128_ty ty) cond reg_true reg_false) 3312 (let ((dst WritableReg (temp_writable_reg $F64)) 3313 (inst MInst (MInst.VecCMov dst cond reg_false reg_true))) 3314 (ConsumesFlags.ConsumesFlagsReturnsReg inst dst))) 3315 3316 3317;; Helpers for generating conditional traps ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3318 3319(decl trap_if (ProducesFlags Cond TrapCode) Reg) 3320(rule (trap_if producer cond trap_code) 3321 (let ((consumer ConsumesFlags (trap_if_impl cond trap_code)) 3322 (_ InstOutput (side_effect (with_flags_side_effect producer consumer)))) 3323 (invalid_reg))) 3324 3325(decl icmps_reg_and_trap (Type Reg Reg Cond TrapCode) Reg) 3326(rule (icmps_reg_and_trap ty src1 src2 cond trap_code) 3327 (let ((_ Unit (emit (MInst.CmpTrapRR (cmpop_cmps ty) 3328 src1 src2 cond trap_code)))) 3329 (invalid_reg))) 3330 3331(decl icmps_simm16_and_trap (Type Reg i16 Cond TrapCode) Reg) 3332(rule (icmps_simm16_and_trap ty src imm cond trap_code) 3333 (let ((_ Unit (emit (MInst.CmpTrapRSImm16 (cmpop_cmps ty) 3334 src imm cond trap_code)))) 3335 (invalid_reg))) 3336 3337(decl icmpu_reg_and_trap (Type Reg Reg Cond TrapCode) Reg) 3338(rule (icmpu_reg_and_trap ty src1 src2 cond trap_code) 3339 (let ((_ Unit (emit (MInst.CmpTrapRR (cmpop_cmpu ty) 3340 src1 src2 cond trap_code)))) 3341 (invalid_reg))) 3342 3343(decl icmpu_uimm16_and_trap (Type Reg u16 Cond TrapCode) Reg) 3344(rule (icmpu_uimm16_and_trap ty src imm cond trap_code) 3345 (let ((_ Unit (emit (MInst.CmpTrapRUImm16 (cmpop_cmpu ty) 3346 src imm cond trap_code)))) 3347 (invalid_reg))) 3348 3349(decl trap_impl (TrapCode) SideEffectNoResult) 3350(rule (trap_impl trap_code) 3351 (SideEffectNoResult.Inst (MInst.Trap trap_code))) 3352 3353(decl trap_if_impl (Cond TrapCode) ConsumesFlags) 3354(rule (trap_if_impl cond trap_code) 3355 (ConsumesFlags.ConsumesFlagsSideEffect (MInst.TrapIf cond trap_code))) 3356 3357(decl debugtrap_impl () SideEffectNoResult) 3358(rule (debugtrap_impl) 3359 (SideEffectNoResult.Inst (MInst.Debugtrap))) 3360 3361 3362;; Helpers for handling boolean conditions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3363 3364;; Capture a flags-producing instruction together with a condition code mask 3365;; that tells how to interpret the resulting condition code. The result can 3366;; be used to represent a boolean condition. 3367(type ProducesBool (enum (ProducesBool (producer ProducesFlags) (cond Cond)))) 3368(decl bool (ProducesFlags Cond) ProducesBool) 3369(rule (bool producer cond) (ProducesBool.ProducesBool producer cond)) 3370 3371;; Invert boolean condition. 3372(decl invert_bool (ProducesBool) ProducesBool) 3373(rule (invert_bool (ProducesBool.ProducesBool producer cond)) 3374 (bool producer (invert_cond cond))) 3375 3376;; Use a boolean condition to select between two registers. 3377(decl select_bool_reg (Type ProducesBool Reg Reg) Reg) 3378(rule (select_bool_reg ty (ProducesBool.ProducesBool producer cond) reg_true reg_false) 3379 (with_flags_reg producer (cmov_reg_reg ty cond reg_true reg_false))) 3380 3381;; Use a boolean condition to select between two immediate values. 3382(decl select_bool_imm (Type ProducesBool i16 i16) Reg) 3383(rule (select_bool_imm ty (ProducesBool.ProducesBool producer cond) imm_true imm_false) 3384 (with_flags_reg producer (cmov_imm_imm ty cond imm_true imm_false))) 3385 3386;; Lower a boolean condition to the values 1/0. This rule is only used in the 3387;; context of instructions that return $I8 results. 3388(decl lower_bool (Type ProducesBool) Reg) 3389(rule (lower_bool $I8 cond) (select_bool_imm $I8 cond 1 0)) 3390 3391;; Lower a boolean condition to the values -1/0. 3392;; 3393;; Recursion: at most once to reduce 128-bit to 64-bit case. 3394(decl rec lower_bool_to_mask (Type ProducesBool) Reg) 3395(rule 0 (lower_bool_to_mask (fits_in_64 ty) producer) 3396 (select_bool_imm ty producer -1 0)) 3397 3398(rule 1 (lower_bool_to_mask $I128 producer) 3399 (let ((res Reg (lower_bool_to_mask $I64 producer))) 3400 (mov_to_vec128 $I128 res res))) 3401 3402;; Emit a conditional branch based on a boolean condition. 3403(decl cond_br_bool (ProducesBool MachLabel MachLabel) SideEffectNoResult) 3404(rule (cond_br_bool (ProducesBool.ProducesBool producer cond) taken not_taken) 3405 (with_flags_side_effect producer (cond_br taken not_taken cond))) 3406 3407;; Emit a conditional trap based on a boolean condition. 3408(decl trap_if_bool (ProducesBool TrapCode) SideEffectNoResult) 3409(rule (trap_if_bool (ProducesBool.ProducesBool producer cond) trap_code) 3410 (with_flags_side_effect producer (trap_if_impl cond trap_code))) 3411 3412 3413;;;; Helpers for compare-and-swap loops ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3414 3415;; We use the emit_loop functionality to create compare-and-swap loops. 3416;; As noted there, code inside a loop emitted via emit_loop cannot write 3417;; to any virtual register, only hard registers. We use the two reserved 3418;; registers %r0 and %r1 in compare-and-swap loops. 3419 3420;; %r0 always holds the value currently loaded from the memory location. 3421(decl casloop_val_reg () WritableReg) 3422(rule (casloop_val_reg) (writable_gpr 0)) 3423 3424;; %r1 is available to compute the new value to be written. 3425(decl casloop_tmp_reg () WritableReg) 3426(rule (casloop_tmp_reg) (writable_gpr 1)) 3427 3428;; This takes a loop body for a compare-and-swap loop, completes it by 3429;; adding the actual compare-and-swap instruction, and emits the initial 3430;; memory load followed by the loop itself. "val" is the new value to 3431;; be written if the memory location still holds the old value in %r0. 3432;; The result should be passed to "casloop_result" or (in the case of 3433;; subword loops) to "casloop_rotate_result". 3434(decl casloop_emit (VecMInstBuilder Type MemFlags Reg Reg) PReg) 3435(rule (casloop_emit ib ty flags aligned_addr val) 3436 (let ( 3437 ;; Construct a memory argument for the aligned word. 3438 (aligned_mem MemArg (memarg_reg_plus_off aligned_addr 0 0 flags)) 3439 ;; Add the compare-and-swap instruction to the builder. 3440 (result Reg (push_atomic_cas ib (ty_ext32 ty) 3441 (casloop_val_reg) val aligned_mem)) 3442 ;; Emit initial load followed by compare-and-swap loop. 3443 (_ Unit (emit_load (ty_ext32 ty) (casloop_val_reg) aligned_mem)) 3444 (_ Unit (emit_loop ib (intcc_as_cond (IntCC.NotEqual))))) 3445 3446 ;; push_atomic_cas above returns its destination register argument, 3447 ;; cas_loop_val_reg, as its result. As cas_loop_val_reg is a writable 3448 ;; version of `gpr 0`, we return that directly here as a physical 3449 ;; register to avoid accidentally using it with a non-preg move 3450 ;; instruction. 3451 (preg_gpr_0))) 3452 3453;; Compute the previous memory value after a (fullword) compare-and-swap loop. 3454;; In the big-endian case, the value is already correct, but may need to be 3455;; copied out of the hard register. In the little-endian case, we need to 3456;; byte-swap since the compare-and-swap instruction is always big-endian. 3457(decl casloop_result (Type MemFlags PReg) Reg) 3458(rule 1 (casloop_result (ty_32_or_64 ty) (bigendian) result) 3459 (mov_preg result)) 3460(rule (casloop_result (ty_32_or_64 ty) (littleendian) result) 3461 (bswap_reg ty (preg_to_reg result))) 3462 3463;; Emit a fullword compare-and-swap loop, returning the previous memory value. 3464(decl casloop (VecMInstBuilder Type MemFlags Reg Reg) Reg) 3465(rule (casloop ib ty flags aligned_addr val) 3466 (casloop_result ty flags (casloop_emit ib ty flags aligned_addr val))) 3467 3468;; For types smaller than $I32, we have no native compare-and-swap 3469;; instruction, so we need to perform the compare-and-swap loop on the 3470;; surrounding aligned word. To actually operate on the target $I8 or 3471;; $I16 data, that aligned word then needs to be rotated by an amount 3472;; determined by the low address bits. 3473 3474;; Determine the rotate amount to bring the target data into a position 3475;; in the high bytes of the enclosing $I32. Since the compare-and-swap 3476;; instruction performs a big-endian memory access, this can be done by 3477;; rotating (left) by "(addr & 3) * 8" bits, or "(addr << 3) & 31" bits. 3478;; We can omit the "& 31" since this is implicit with a 32-bit rotate. 3479(decl casloop_bitshift (Reg) Reg) 3480(rule (casloop_bitshift addr) 3481 (lshl_imm $I32 addr 3)) 3482 3483;; The address of the surrounding 32-bit word, by masking off low bits. 3484(decl casloop_aligned_addr (Reg) Reg) 3485(rule (casloop_aligned_addr addr) 3486 (and_uimm16shifted $I64 addr (uimm16shifted 0xfffc 0))) 3487 3488;; Push an instruction sequence to rotate a value loaded from memory 3489;; to the well-defined location: the high bytes in case of a big-endian 3490;; memory operation, and the low bytes in the little-endian case. 3491;; (This is somewhat arbitrary but chosen to allow the most efficient 3492;; sequences to compute the various atomic operations.) 3493;; Note that $I8 accesses always use the big-endian case. 3494(decl casloop_rotate_in (VecMInstBuilder Type MemFlags Reg Reg) Reg) 3495(rule (casloop_rotate_in ib $I8 _ bitshift val) 3496 (push_rot_imm_reg ib $I32 (casloop_tmp_reg) val 0 bitshift)) 3497(rule 1 (casloop_rotate_in ib $I16 (bigendian) bitshift val) 3498 (push_rot_imm_reg ib $I32 (casloop_tmp_reg) val 0 bitshift)) 3499(rule (casloop_rotate_in ib $I16 (littleendian) bitshift val) 3500 (push_rot_imm_reg ib $I32 (casloop_tmp_reg) val 16 bitshift)) 3501 3502;; The inverse operation: rotate values back to the original memory order. 3503;; This can be done by simply using the negated shift count. As an extra 3504;; optimization, we note that in the $I16 case the shift count can only 3505;; take the values 0 or 16, both of which negate to themselves (mod 32), 3506;; so the explicit negation operation can be omitted here. 3507(decl casloop_rotate_out (VecMInstBuilder Type MemFlags Reg Reg) Reg) 3508(rule (casloop_rotate_out ib $I8 _ bitshift val) 3509 (push_rot_imm_reg ib $I32 (casloop_tmp_reg) val 0 (neg_reg $I32 bitshift))) 3510(rule 1 (casloop_rotate_out ib $I16 (bigendian) bitshift val) 3511 (push_rot_imm_reg ib $I32 (casloop_tmp_reg) val 0 bitshift)) 3512(rule (casloop_rotate_out ib $I16 (littleendian) bitshift val) 3513 (push_rot_imm_reg ib $I32 (casloop_tmp_reg) val 16 bitshift)) 3514 3515;; Compute the previous memory value after a subword compare-and-swap loop. 3516;; This is similar to casloop_rotate_in, but brings the value to the *low* 3517;; bytes. This can be achieved simply by adding the type size to the rotate 3518;; amount, which can be done within the same instruction. In the little- 3519;; endian case, we also need to byte-swap the result. Since we only have 3520;; a 32-bit byte-swap instruction, we load the value to the high bytes in 3521;; this case before performing the 32-bit byte-swap. 3522(decl casloop_rotate_result (Type MemFlags Reg Reg) Reg) 3523(rule (casloop_rotate_result $I8 _ bitshift result) 3524 (rot_imm_reg $I32 result 8 bitshift)) 3525(rule 1 (casloop_rotate_result $I16 (bigendian) bitshift result) 3526 (rot_imm_reg $I32 result 16 bitshift)) 3527(rule (casloop_rotate_result $I16 (littleendian) bitshift result) 3528 (bswap_reg $I32 (rot_reg $I32 result bitshift))) 3529 3530;; Emit a subword compare-and-swap loop, returning the previous memory value. 3531(decl casloop_subword (VecMInstBuilder Type MemFlags Reg Reg Reg) Reg) 3532(rule (casloop_subword ib ty flags aligned_addr bitshift val) 3533 (casloop_rotate_result ty flags bitshift 3534 (casloop_emit ib ty flags aligned_addr val))) 3535 3536 3537;; Helpers for generating `call` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3538 3539(decl gen_call_info (Sig CallInstDest CallArgList CallRetList OptionTryCallInfo bool) BoxCallInfo) 3540(extern constructor gen_call_info gen_call_info) 3541 3542(decl gen_return_call_info (Sig CallInstDest CallArgList) BoxReturnCallInfo) 3543(extern constructor gen_return_call_info gen_return_call_info) 3544 3545(decl abi_emit_call_adjust_stack (Sig) Unit) 3546(extern constructor abi_emit_call_adjust_stack abi_emit_call_adjust_stack) 3547 3548(decl abi_emit_return_call_adjust_stack (Sig) Unit) 3549(extern constructor abi_emit_return_call_adjust_stack abi_emit_return_call_adjust_stack) 3550 3551(decl abi_prepare_args (Sig ValueSlice) ValueRegsVec) 3552(extern constructor abi_prepare_args abi_prepare_args) 3553 3554(decl writable_link_reg () WritableReg) 3555(rule (writable_link_reg) (writable_gpr 14)) 3556 3557 3558;; Helpers for generating vector pack and unpack instructions ;;;;;;;;;;;;;;;;;; 3559 3560(decl vec_widen_type (Type) Type) 3561(rule (vec_widen_type $I8X16) $I16X8) 3562(rule (vec_widen_type $I16X8) $I32X4) 3563(rule (vec_widen_type $I32X4) $I64X2) 3564 3565(decl vecop_pack (Type) VecBinaryOp) 3566(rule (vecop_pack $I16X8) (VecBinaryOp.Pack16x8)) 3567(rule (vecop_pack $I32X4) (VecBinaryOp.Pack32x4)) 3568(rule (vecop_pack $I64X2) (VecBinaryOp.Pack64x2)) 3569 3570(decl vec_pack (Type Reg Reg) Reg) 3571(rule (vec_pack ty x y) (vec_rrr ty (vecop_pack ty) x y)) 3572 3573(decl vecop_pack_ssat (Type) VecBinaryOp) 3574(rule (vecop_pack_ssat $I16X8) (VecBinaryOp.PackSSat16x8)) 3575(rule (vecop_pack_ssat $I32X4) (VecBinaryOp.PackSSat32x4)) 3576(rule (vecop_pack_ssat $I64X2) (VecBinaryOp.PackSSat64x2)) 3577 3578(decl vec_pack_ssat (Type Reg Reg) Reg) 3579(rule (vec_pack_ssat ty x y) (vec_rrr ty (vecop_pack_ssat ty) x y)) 3580 3581(decl vecop_pack_usat (Type) VecBinaryOp) 3582(rule (vecop_pack_usat $I16X8) (VecBinaryOp.PackUSat16x8)) 3583(rule (vecop_pack_usat $I32X4) (VecBinaryOp.PackUSat32x4)) 3584(rule (vecop_pack_usat $I64X2) (VecBinaryOp.PackUSat64x2)) 3585 3586(decl vec_pack_usat (Type Reg Reg) Reg) 3587(rule (vec_pack_usat ty x y) (vec_rrr ty (vecop_pack_usat ty) x y)) 3588 3589(decl vecop_unpacks_low (Type) VecUnaryOp) 3590(rule (vecop_unpacks_low $I8X16) (VecUnaryOp.UnpackSLow8x16)) 3591(rule (vecop_unpacks_low $I16X8) (VecUnaryOp.UnpackSLow16x8)) 3592(rule (vecop_unpacks_low $I32X4) (VecUnaryOp.UnpackSLow32x4)) 3593 3594(decl vec_unpacks_low (Type Reg) Reg) 3595(rule (vec_unpacks_low ty x) (vec_rr ty (vecop_unpacks_low ty) x)) 3596 3597(decl vecop_unpacks_high (Type) VecUnaryOp) 3598(rule (vecop_unpacks_high $I8X16) (VecUnaryOp.UnpackSHigh8x16)) 3599(rule (vecop_unpacks_high $I16X8) (VecUnaryOp.UnpackSHigh16x8)) 3600(rule (vecop_unpacks_high $I32X4) (VecUnaryOp.UnpackSHigh32x4)) 3601 3602(decl vec_unpacks_high (Type Reg) Reg) 3603(rule (vec_unpacks_high ty x) (vec_rr ty (vecop_unpacks_high ty) x)) 3604 3605(decl vecop_unpacku_low (Type) VecUnaryOp) 3606(rule (vecop_unpacku_low $I8X16) (VecUnaryOp.UnpackULow8x16)) 3607(rule (vecop_unpacku_low $I16X8) (VecUnaryOp.UnpackULow16x8)) 3608(rule (vecop_unpacku_low $I32X4) (VecUnaryOp.UnpackULow32x4)) 3609 3610(decl vec_unpacku_low (Type Reg) Reg) 3611(rule (vec_unpacku_low ty x) (vec_rr ty (vecop_unpacku_low ty) x)) 3612 3613(decl vecop_unpacku_high (Type) VecUnaryOp) 3614(rule (vecop_unpacku_high $I8X16) (VecUnaryOp.UnpackUHigh8x16)) 3615(rule (vecop_unpacku_high $I16X8) (VecUnaryOp.UnpackUHigh16x8)) 3616(rule (vecop_unpacku_high $I32X4) (VecUnaryOp.UnpackUHigh32x4)) 3617 3618(decl vec_unpacku_high (Type Reg) Reg) 3619(rule (vec_unpacku_high ty x) (vec_rr ty (vecop_unpacku_high ty) x)) 3620 3621;; Versions of pack using current lane order semantics. 3622;; First source operand contains values that will end up in the 3623;; lower-numbered lanes of the result, second operand contains 3624;; values that will end up in the higher-numbered lanes. 3625 3626(decl vec_pack_lane_order (Type Reg Reg) Reg) 3627(rule 1 (vec_pack_lane_order ty x y) 3628 (if-let (LaneOrder.BigEndian) (lane_order)) 3629 (vec_pack ty x y)) 3630(rule (vec_pack_lane_order ty x y) 3631 (if-let (LaneOrder.LittleEndian) (lane_order)) 3632 (vec_pack ty y x)) 3633 3634(decl vec_pack_ssat_lane_order (Type Reg Reg) Reg) 3635(rule 1 (vec_pack_ssat_lane_order ty x y) 3636 (if-let (LaneOrder.BigEndian) (lane_order)) 3637 (vec_pack_ssat ty x y)) 3638(rule (vec_pack_ssat_lane_order ty x y) 3639 (if-let (LaneOrder.LittleEndian) (lane_order)) 3640 (vec_pack_ssat ty y x)) 3641 3642(decl vec_pack_usat_lane_order (Type Reg Reg) Reg) 3643(rule 1 (vec_pack_usat_lane_order ty x y) 3644 (if-let (LaneOrder.BigEndian) (lane_order)) 3645 (vec_pack_usat ty x y)) 3646(rule (vec_pack_usat_lane_order ty x y) 3647 (if-let (LaneOrder.LittleEndian) (lane_order)) 3648 (vec_pack_usat ty y x)) 3649 3650;; Versions of unpack using current lane order semantics. 3651;; unpack_low will consume values from the lower-numbered 3652;; lanes of the input, and unpack_high will consume values 3653;; from higher-numbered lanes. 3654 3655(decl vec_unpacks_low_lane_order (Type Reg) Reg) 3656(rule 1 (vec_unpacks_low_lane_order ty x) 3657 (if-let (LaneOrder.BigEndian) (lane_order)) 3658 (vec_unpacks_high ty x)) 3659(rule (vec_unpacks_low_lane_order ty x) 3660 (if-let (LaneOrder.LittleEndian) (lane_order)) 3661 (vec_unpacks_low ty x)) 3662 3663(decl vec_unpacks_high_lane_order (Type Reg) Reg) 3664(rule 1 (vec_unpacks_high_lane_order ty x) 3665 (if-let (LaneOrder.BigEndian) (lane_order)) 3666 (vec_unpacks_low ty x)) 3667(rule (vec_unpacks_high_lane_order ty x) 3668 (if-let (LaneOrder.LittleEndian) (lane_order)) 3669 (vec_unpacks_high ty x)) 3670 3671(decl vec_unpacku_low_lane_order (Type Reg) Reg) 3672(rule 1 (vec_unpacku_low_lane_order ty x) 3673 (if-let (LaneOrder.BigEndian) (lane_order)) 3674 (vec_unpacku_high ty x)) 3675(rule (vec_unpacku_low_lane_order ty x) 3676 (if-let (LaneOrder.LittleEndian) (lane_order)) 3677 (vec_unpacku_low ty x)) 3678 3679(decl vec_unpacku_high_lane_order (Type Reg) Reg) 3680(rule 1 (vec_unpacku_high_lane_order ty x) 3681 (if-let (LaneOrder.BigEndian) (lane_order)) 3682 (vec_unpacku_low ty x)) 3683(rule (vec_unpacku_high_lane_order ty x) 3684 (if-let (LaneOrder.LittleEndian) (lane_order)) 3685 (vec_unpacku_high ty x)) 3686 3687 3688;; Helpers for generating vector merge instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3689 3690(decl vecop_merge_low (Type) VecBinaryOp) 3691(rule (vecop_merge_low $I8X16) (VecBinaryOp.MergeLow8x16)) 3692(rule (vecop_merge_low $I16X8) (VecBinaryOp.MergeLow16x8)) 3693(rule (vecop_merge_low $I32X4) (VecBinaryOp.MergeLow32x4)) 3694(rule (vecop_merge_low $I64X2) (VecBinaryOp.MergeLow64x2)) 3695 3696(decl vec_merge_low (Type Reg Reg) Reg) 3697(rule (vec_merge_low ty x y) (vec_rrr ty (vecop_merge_low ty) x y)) 3698 3699(decl vecop_merge_high (Type) VecBinaryOp) 3700(rule (vecop_merge_high $I8X16) (VecBinaryOp.MergeHigh8x16)) 3701(rule (vecop_merge_high $I16X8) (VecBinaryOp.MergeHigh16x8)) 3702(rule (vecop_merge_high $I32X4) (VecBinaryOp.MergeHigh32x4)) 3703(rule (vecop_merge_high $I64X2) (VecBinaryOp.MergeHigh64x2)) 3704 3705(decl vec_merge_high (Type Reg Reg) Reg) 3706(rule (vec_merge_high ty x y) (vec_rrr ty (vecop_merge_high ty) x y)) 3707 3708;; Versions of merge using current lane order semantics. 3709;; merge_low will consume values from the lower-numbered 3710;; lanes of the inputs, and merge_high will consume values 3711;; from higher-numbered lanes. In both cases, values from 3712;; the first input will end up in even-numbered lanes, and 3713;; values from the second input will end up in odd-numbered 3714;; lanes of the output. 3715 3716(decl vec_merge_low_lane_order (Type Reg Reg) Reg) 3717(rule 1 (vec_merge_low_lane_order ty x y) 3718 (if-let (LaneOrder.BigEndian) (lane_order)) 3719 (vec_merge_high ty x y)) 3720(rule (vec_merge_low_lane_order ty x y) 3721 (if-let (LaneOrder.LittleEndian) (lane_order)) 3722 (vec_merge_low ty y x)) 3723 3724(decl vec_merge_high_lane_order (Type Reg Reg) Reg) 3725(rule 1 (vec_merge_high_lane_order ty x y) 3726 (if-let (LaneOrder.BigEndian) (lane_order)) 3727 (vec_merge_low ty x y)) 3728(rule (vec_merge_high_lane_order ty x y) 3729 (if-let (LaneOrder.LittleEndian) (lane_order)) 3730 (vec_merge_high ty y x)) 3731 3732 3733;; Helpers for generating `clz` and `ctz` instructions ;;;;;;;;;;;;;;;;;;;;;;;;; 3734 3735;; Count leading zeroes via FLOGR. For a zero input, return the specified value. 3736(decl clz_flogr_reg (i16 Reg) Reg) 3737 3738;; The flogr instruction returns 64 for zero input by default. 3739(rule (clz_flogr_reg 64 x) 3740 (let ((dst WritableRegPair (temp_writable_regpair $I64)) 3741 (_ Unit (emit (MInst.Flogr dst x)))) 3742 (regpair_hi dst))) 3743 3744;; If another zero return value was requested, we need to override the flogr result. 3745(rule -1 (clz_flogr_reg zeroval x) 3746 (let ((tmp WritableRegPair (temp_writable_regpair $I64))) 3747 (with_flags_reg 3748 (ProducesFlags.ProducesFlagsSideEffect (MInst.Flogr tmp x)) 3749 (cmov_imm $I64 (intcc_as_cond (IntCC.Equal)) zeroval (regpair_hi tmp))))) 3750 3751;; Count leading zeros (z17 instruction). 3752(decl clz_reg (Reg) Reg) 3753(rule (clz_reg x) (unary_rr $I64 (UnaryOp.Clz64) x)) 3754 3755;; Count trailing zeros (z17 instruction). 3756(decl ctz_reg (Reg) Reg) 3757(rule (ctz_reg x) (unary_rr $I64 (UnaryOp.Ctz64) x)) 3758 3759;; Vector count leading zeros. 3760(decl vecop_clz (Type) VecUnaryOp) 3761(rule (vecop_clz $I8X16) (VecUnaryOp.Clz8x16)) 3762(rule (vecop_clz $I16X8) (VecUnaryOp.Clz16x8)) 3763(rule (vecop_clz $I32X4) (VecUnaryOp.Clz32x4)) 3764(rule (vecop_clz $I64X2) (VecUnaryOp.Clz64x2)) 3765(rule (vecop_clz $I128) (VecUnaryOp.Clz128)) 3766 3767(decl vec_clz (Type Reg) Reg) 3768(rule (vec_clz ty x) (vec_rr ty (vecop_clz ty) x)) 3769 3770;; Vector count trailing zeros. 3771(decl vecop_ctz (Type) VecUnaryOp) 3772(rule (vecop_ctz $I8X16) (VecUnaryOp.Ctz8x16)) 3773(rule (vecop_ctz $I16X8) (VecUnaryOp.Ctz16x8)) 3774(rule (vecop_ctz $I32X4) (VecUnaryOp.Ctz32x4)) 3775(rule (vecop_ctz $I64X2) (VecUnaryOp.Ctz64x2)) 3776(rule (vecop_ctz $I128) (VecUnaryOp.Ctz128)) 3777 3778(decl vec_ctz (Type Reg) Reg) 3779(rule (vec_ctz ty x) (vec_rr ty (vecop_ctz ty) x)) 3780 3781 3782;; Helpers for generating saturating integer instructions ;;;;;;;;;;;;;;;;;;;;;; 3783 3784(decl uint_sat_reg (Type Type Reg) Reg) 3785(rule 1 (uint_sat_reg ty ty reg) reg) 3786(rule (uint_sat_reg $I8 (ty_32_or_64 ty) reg) 3787 (with_flags_reg (icmpu_uimm32 ty reg 256) 3788 (cmov_imm ty (intcc_as_cond (IntCC.UnsignedGreaterThan)) 255 reg))) 3789(rule (uint_sat_reg $I16 (ty_32_or_64 ty) reg) 3790 (with_flags_reg (icmpu_uimm32 ty reg 65535) 3791 (cmov_imm ty (intcc_as_cond (IntCC.UnsignedGreaterThan)) -1 reg))) 3792(rule (uint_sat_reg $I32 $I64 reg) 3793 (let ((bound Reg (imm $I64 4294967295)) 3794 (cond ProducesBool 3795 (bool (icmpu_reg $I64 reg bound) 3796 (intcc_as_cond (IntCC.UnsignedGreaterThan))))) 3797 (select_bool_reg $I64 cond bound reg))) 3798 3799(decl sint_sat_reg (Type Type Reg) Reg) 3800(rule 1 (sint_sat_reg ty ty reg) reg) 3801(rule (sint_sat_reg $I8 (ty_32_or_64 ty) reg) 3802 (let ((ub Reg (with_flags_reg (icmps_simm16 ty reg 127) 3803 (cmov_imm ty 3804 (intcc_as_cond (IntCC.SignedGreaterThan)) 127 reg)))) 3805 (with_flags_reg (icmps_simm16 ty ub -128) 3806 (cmov_imm ty (intcc_as_cond (IntCC.SignedLessThan)) -128 ub)))) 3807(rule (sint_sat_reg $I16 (ty_32_or_64 ty) reg) 3808 (let ((ub Reg (with_flags_reg (icmps_simm16 ty reg 32767) 3809 (cmov_imm ty 3810 (intcc_as_cond (IntCC.SignedGreaterThan)) 32767 reg)))) 3811 (with_flags_reg (icmps_simm16 ty ub -32768) 3812 (cmov_imm ty (intcc_as_cond (IntCC.SignedLessThan)) -32768 ub)))) 3813(rule (sint_sat_reg $I32 $I64 reg) 3814 (let ((u_bound Reg (imm32 $I64 2147483647)) 3815 (u_cond ProducesBool 3816 (bool (icmps_reg $I64 reg u_bound) 3817 (intcc_as_cond (IntCC.SignedGreaterThan)))) 3818 (ub Reg (select_bool_reg $I64 u_cond u_bound reg)) 3819 (l_bound Reg (imm32 $I64 -2147483648)) 3820 (l_cond ProducesBool 3821 (bool (icmps_reg $I64 ub l_bound) 3822 (intcc_as_cond (IntCC.SignedLessThan))))) 3823 (select_bool_reg $I64 l_cond l_bound ub))) 3824 3825 3826;; Helpers for generating `add` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3827 3828(decl aluop_add (Type) ALUOp) 3829(rule (aluop_add $I8) (ALUOp.Add32)) 3830(rule (aluop_add $I16) (ALUOp.Add32)) 3831(rule (aluop_add $I32) (ALUOp.Add32)) 3832(rule (aluop_add $I64) (ALUOp.Add64)) 3833 3834(decl aluop_add_sext16 (Type) ALUOp) 3835(rule (aluop_add_sext16 $I16) (ALUOp.Add32Ext16)) 3836(rule (aluop_add_sext16 $I32) (ALUOp.Add32Ext16)) 3837(rule (aluop_add_sext16 $I64) (ALUOp.Add64Ext16)) 3838 3839(decl aluop_add_sext32 (Type) ALUOp) 3840(rule (aluop_add_sext32 $I64) (ALUOp.Add64Ext32)) 3841 3842(decl add_reg (Type Reg Reg) Reg) 3843(rule (add_reg ty x y) (alu_rrr ty (aluop_add ty) x y)) 3844 3845(decl add_reg_sext32 (Type Reg Reg) Reg) 3846(rule (add_reg_sext32 ty x y) (alu_rr ty (aluop_add_sext32 ty) x y)) 3847 3848(decl add_simm16 (Type Reg i16) Reg) 3849(rule (add_simm16 ty x y) (alu_rrsimm16 ty (aluop_add ty) x y)) 3850 3851(decl add_simm32 (Type Reg i32) Reg) 3852(rule (add_simm32 ty x y) (alu_rsimm32 ty (aluop_add ty) x y)) 3853 3854(decl add_mem (Type Reg MemArg) Reg) 3855(rule (add_mem ty x y) (alu_rx ty (aluop_add ty) x y)) 3856 3857(decl add_mem_sext16 (Type Reg MemArg) Reg) 3858(rule (add_mem_sext16 ty x y) (alu_rx ty (aluop_add_sext16 ty) x y)) 3859 3860(decl add_mem_sext32 (Type Reg MemArg) Reg) 3861(rule (add_mem_sext32 ty x y) (alu_rx ty (aluop_add_sext32 ty) x y)) 3862 3863(decl vecop_add (Type) VecBinaryOp) 3864(rule (vecop_add $I8X16) (VecBinaryOp.Add8x16)) 3865(rule (vecop_add $I16X8) (VecBinaryOp.Add16x8)) 3866(rule (vecop_add $I32X4) (VecBinaryOp.Add32x4)) 3867(rule (vecop_add $I64X2) (VecBinaryOp.Add64x2)) 3868(rule (vecop_add $I128) (VecBinaryOp.Add128)) 3869 3870(decl vec_add (Type Reg Reg) Reg) 3871(rule (vec_add ty x y) (vec_rrr ty (vecop_add ty) x y)) 3872 3873 3874;; Helpers for generating `add_logical` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;; 3875 3876(decl aluop_add_logical (Type) ALUOp) 3877(rule (aluop_add_logical $I32) (ALUOp.AddLogical32)) 3878(rule (aluop_add_logical $I64) (ALUOp.AddLogical64)) 3879 3880(decl aluop_add_logical_zext32 (Type) ALUOp) 3881(rule (aluop_add_logical_zext32 $I64) (ALUOp.AddLogical64Ext32)) 3882 3883(decl add_logical_reg (Type Reg Reg) Reg) 3884(rule (add_logical_reg ty x y) (alu_rrr ty (aluop_add_logical ty) x y)) 3885 3886(decl add_logical_reg_with_flags_paired (Type Reg Reg) ProducesFlags) 3887(rule (add_logical_reg_with_flags_paired ty x y) 3888 (alu_rrr_with_flags_paired ty (aluop_add_logical ty) x y)) 3889 3890(decl add_logical_reg_zext32 (Type Reg Reg) Reg) 3891(rule (add_logical_reg_zext32 ty x y) (alu_rr ty (aluop_add_logical_zext32 ty) x y)) 3892 3893(decl add_logical_reg_zext32_with_flags_paired (Type Reg Reg) ProducesFlags) 3894(rule (add_logical_reg_zext32_with_flags_paired ty x y) 3895 (alu_rr_with_flags_paired ty (aluop_add_logical_zext32 ty) x y)) 3896 3897(decl add_logical_zimm32 (Type Reg u32) Reg) 3898(rule (add_logical_zimm32 ty x y) (alu_ruimm32 ty (aluop_add_logical ty) x y)) 3899 3900(decl add_logical_zimm32_with_flags_paired (Type Reg u32) ProducesFlags) 3901(rule (add_logical_zimm32_with_flags_paired ty x y) 3902 (alu_ruimm32_with_flags_paired ty (aluop_add_logical ty) x y)) 3903 3904(decl add_logical_mem (Type Reg MemArg) Reg) 3905(rule (add_logical_mem ty x y) (alu_rx ty (aluop_add_logical ty) x y)) 3906 3907(decl add_logical_mem_with_flags_paired (Type Reg MemArg) ProducesFlags) 3908(rule (add_logical_mem_with_flags_paired ty x y) 3909 (alu_rx_with_flags_paired ty (aluop_add_logical ty) x y)) 3910 3911(decl add_logical_mem_zext32 (Type Reg MemArg) Reg) 3912(rule (add_logical_mem_zext32 ty x y) (alu_rx ty (aluop_add_logical_zext32 ty) x y)) 3913 3914(decl add_logical_mem_zext32_with_flags_paired (Type Reg MemArg) ProducesFlags) 3915(rule (add_logical_mem_zext32_with_flags_paired ty x y) 3916 (alu_rx_with_flags_paired ty (aluop_add_logical_zext32 ty) x y)) 3917 3918 3919;; Helpers for generating `sub` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3920 3921(decl aluop_sub (Type) ALUOp) 3922(rule (aluop_sub $I8) (ALUOp.Sub32)) 3923(rule (aluop_sub $I16) (ALUOp.Sub32)) 3924(rule (aluop_sub $I32) (ALUOp.Sub32)) 3925(rule (aluop_sub $I64) (ALUOp.Sub64)) 3926 3927(decl aluop_sub_sext16 (Type) ALUOp) 3928(rule (aluop_sub_sext16 $I16) (ALUOp.Sub32Ext16)) 3929(rule (aluop_sub_sext16 $I32) (ALUOp.Sub32Ext16)) 3930(rule (aluop_sub_sext16 $I64) (ALUOp.Sub64Ext16)) 3931 3932(decl aluop_sub_sext32 (Type) ALUOp) 3933(rule (aluop_sub_sext32 $I64) (ALUOp.Sub64Ext32)) 3934 3935(decl sub_reg (Type Reg Reg) Reg) 3936(rule (sub_reg ty x y) (alu_rrr ty (aluop_sub ty) x y)) 3937 3938(decl sub_reg_sext32 (Type Reg Reg) Reg) 3939(rule (sub_reg_sext32 ty x y) (alu_rr ty (aluop_sub_sext32 ty) x y)) 3940 3941(decl sub_mem (Type Reg MemArg) Reg) 3942(rule (sub_mem ty x y) (alu_rx ty (aluop_sub ty) x y)) 3943 3944(decl sub_mem_sext16 (Type Reg MemArg) Reg) 3945(rule (sub_mem_sext16 ty x y) (alu_rx ty (aluop_sub_sext16 ty) x y)) 3946 3947(decl sub_mem_sext32 (Type Reg MemArg) Reg) 3948(rule (sub_mem_sext32 ty x y) (alu_rx ty (aluop_sub_sext32 ty) x y)) 3949 3950(decl vecop_sub (Type) VecBinaryOp) 3951(rule (vecop_sub $I8X16) (VecBinaryOp.Sub8x16)) 3952(rule (vecop_sub $I16X8) (VecBinaryOp.Sub16x8)) 3953(rule (vecop_sub $I32X4) (VecBinaryOp.Sub32x4)) 3954(rule (vecop_sub $I64X2) (VecBinaryOp.Sub64x2)) 3955(rule (vecop_sub $I128) (VecBinaryOp.Sub128)) 3956 3957(decl vec_sub (Type Reg Reg) Reg) 3958(rule (vec_sub ty x y) (vec_rrr ty (vecop_sub ty) x y)) 3959 3960 3961;; Helpers for generating `sub_logical` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;; 3962 3963(decl aluop_sub_logical (Type) ALUOp) 3964(rule (aluop_sub_logical $I32) (ALUOp.SubLogical32)) 3965(rule (aluop_sub_logical $I64) (ALUOp.SubLogical64)) 3966 3967(decl aluop_sub_logical_zext32 (Type) ALUOp) 3968(rule (aluop_sub_logical_zext32 $I64) (ALUOp.SubLogical64Ext32)) 3969 3970(decl sub_logical_reg (Type Reg Reg) Reg) 3971(rule (sub_logical_reg ty x y) (alu_rrr ty (aluop_sub_logical ty) x y)) 3972 3973(decl sub_logical_reg_zext32 (Type Reg Reg) Reg) 3974(rule (sub_logical_reg_zext32 ty x y) (alu_rr ty (aluop_sub_logical_zext32 ty) x y)) 3975 3976(decl sub_logical_zimm32 (Type Reg u32) Reg) 3977(rule (sub_logical_zimm32 ty x y) (alu_ruimm32 ty (aluop_sub_logical ty) x y)) 3978 3979(decl sub_logical_mem (Type Reg MemArg) Reg) 3980(rule (sub_logical_mem ty x y) (alu_rx ty (aluop_sub_logical ty) x y)) 3981 3982(decl sub_logical_mem_zext32 (Type Reg MemArg) Reg) 3983(rule (sub_logical_mem_zext32 ty x y) (alu_rx ty (aluop_sub_logical ty) x y)) 3984 3985 3986;; Helpers for generating `mul` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 3987 3988(decl aluop_mul (Type) ALUOp) 3989(rule (aluop_mul $I8) (ALUOp.Mul32)) 3990(rule (aluop_mul $I16) (ALUOp.Mul32)) 3991(rule (aluop_mul $I32) (ALUOp.Mul32)) 3992(rule (aluop_mul $I64) (ALUOp.Mul64)) 3993 3994(decl aluop_mul_sext16 (Type) ALUOp) 3995(rule (aluop_mul_sext16 $I16) (ALUOp.Mul32Ext16)) 3996(rule (aluop_mul_sext16 $I32) (ALUOp.Mul32Ext16)) 3997(rule (aluop_mul_sext16 $I64) (ALUOp.Mul64Ext16)) 3998 3999(decl aluop_mul_sext32 (Type) ALUOp) 4000(rule (aluop_mul_sext32 $I64) (ALUOp.Mul64Ext32)) 4001 4002(decl mul_reg (Type Reg Reg) Reg) 4003(rule (mul_reg ty x y) (alu_rrr ty (aluop_mul ty) x y)) 4004 4005(decl mul_reg_sext32 (Type Reg Reg) Reg) 4006(rule (mul_reg_sext32 ty x y) (alu_rr ty (aluop_mul_sext32 ty) x y)) 4007 4008(decl mul_simm16 (Type Reg i16) Reg) 4009(rule (mul_simm16 ty x y) (alu_rsimm16 ty (aluop_mul ty) x y)) 4010 4011(decl mul_simm32 (Type Reg i32) Reg) 4012(rule (mul_simm32 ty x y) (alu_rsimm32 ty (aluop_mul ty) x y)) 4013 4014(decl mul_mem (Type Reg MemArg) Reg) 4015(rule (mul_mem ty x y) (alu_rx ty (aluop_mul ty) x y)) 4016 4017(decl mul_mem_sext16 (Type Reg MemArg) Reg) 4018(rule (mul_mem_sext16 ty x y) (alu_rx ty (aluop_mul_sext16 ty) x y)) 4019 4020(decl mul_mem_sext32 (Type Reg MemArg) Reg) 4021(rule (mul_mem_sext32 ty x y) (alu_rx ty (aluop_mul_sext32 ty) x y)) 4022 4023(decl vecop_mul (Type) VecBinaryOp) 4024(rule (vecop_mul $I8X16) (VecBinaryOp.Mul8x16)) 4025(rule (vecop_mul $I16X8) (VecBinaryOp.Mul16x8)) 4026(rule (vecop_mul $I32X4) (VecBinaryOp.Mul32x4)) 4027(rule (vecop_mul $I64X2) (VecBinaryOp.Mul64x2)) 4028(rule (vecop_mul $I128) (VecBinaryOp.Mul128)) 4029 4030(decl vec_mul (Type Reg Reg) Reg) 4031(rule (vec_mul ty x y) (vec_rrr ty (vecop_mul ty) x y)) 4032 4033(decl vecop_umulhi (Type) VecBinaryOp) 4034(rule (vecop_umulhi $I8X16) (VecBinaryOp.UMulHi8x16)) 4035(rule (vecop_umulhi $I16X8) (VecBinaryOp.UMulHi16x8)) 4036(rule (vecop_umulhi $I32X4) (VecBinaryOp.UMulHi32x4)) 4037(rule (vecop_umulhi $I64X2) (VecBinaryOp.UMulHi64x2)) 4038(rule (vecop_umulhi $I128) (VecBinaryOp.UMulHi128)) 4039 4040(decl vec_umulhi (Type Reg Reg) Reg) 4041(rule (vec_umulhi ty x y) (vec_rrr ty (vecop_umulhi ty) x y)) 4042 4043(decl vecop_smulhi (Type) VecBinaryOp) 4044(rule (vecop_smulhi $I8X16) (VecBinaryOp.SMulHi8x16)) 4045(rule (vecop_smulhi $I16X8) (VecBinaryOp.SMulHi16x8)) 4046(rule (vecop_smulhi $I32X4) (VecBinaryOp.SMulHi32x4)) 4047(rule (vecop_smulhi $I64X2) (VecBinaryOp.SMulHi64x2)) 4048(rule (vecop_smulhi $I128) (VecBinaryOp.SMulHi128)) 4049 4050(decl vec_smulhi (Type Reg Reg) Reg) 4051(rule (vec_smulhi ty x y) (vec_rrr ty (vecop_smulhi ty) x y)) 4052 4053(decl vecop_umul_even (Type) VecBinaryOp) 4054(rule (vecop_umul_even $I8X16) (VecBinaryOp.UMulEven8x16)) 4055(rule (vecop_umul_even $I16X8) (VecBinaryOp.UMulEven16x8)) 4056(rule (vecop_umul_even $I32X4) (VecBinaryOp.UMulEven32x4)) 4057(rule (vecop_umul_even $I64X2) (VecBinaryOp.UMulEven64x2)) 4058 4059(decl vec_umul_even (Type Reg Reg) Reg) 4060(rule (vec_umul_even ty x y) (vec_rrr ty (vecop_umul_even ty) x y)) 4061 4062(decl vecop_smul_even (Type) VecBinaryOp) 4063(rule (vecop_smul_even $I8X16) (VecBinaryOp.SMulEven8x16)) 4064(rule (vecop_smul_even $I16X8) (VecBinaryOp.SMulEven16x8)) 4065(rule (vecop_smul_even $I32X4) (VecBinaryOp.SMulEven32x4)) 4066(rule (vecop_smul_even $I64X2) (VecBinaryOp.SMulEven64x2)) 4067 4068(decl vec_smul_even (Type Reg Reg) Reg) 4069(rule (vec_smul_even ty x y) (vec_rrr ty (vecop_smul_even ty) x y)) 4070 4071(decl vecop_umul_odd (Type) VecBinaryOp) 4072(rule (vecop_umul_odd $I8X16) (VecBinaryOp.UMulOdd8x16)) 4073(rule (vecop_umul_odd $I16X8) (VecBinaryOp.UMulOdd16x8)) 4074(rule (vecop_umul_odd $I32X4) (VecBinaryOp.UMulOdd32x4)) 4075(rule (vecop_umul_odd $I64X2) (VecBinaryOp.UMulOdd64x2)) 4076 4077(decl vec_umul_odd (Type Reg Reg) Reg) 4078(rule (vec_umul_odd ty x y) (vec_rrr ty (vecop_umul_odd ty) x y)) 4079 4080(decl vecop_smul_odd (Type) VecBinaryOp) 4081(rule (vecop_smul_odd $I8X16) (VecBinaryOp.SMulOdd8x16)) 4082(rule (vecop_smul_odd $I16X8) (VecBinaryOp.SMulOdd16x8)) 4083(rule (vecop_smul_odd $I32X4) (VecBinaryOp.SMulOdd32x4)) 4084(rule (vecop_smul_odd $I64X2) (VecBinaryOp.SMulOdd64x2)) 4085 4086(decl vec_smul_odd (Type Reg Reg) Reg) 4087(rule (vec_smul_odd ty x y) (vec_rrr ty (vecop_smul_odd ty) x y)) 4088 4089 4090;; Helpers for generating vector divide instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;; 4091 4092(decl vecop_sdiv (Type) VecBinaryOp) 4093(rule (vecop_sdiv $I32X4) (VecBinaryOp.SDiv32x4)) 4094(rule (vecop_sdiv $I64X2) (VecBinaryOp.SDiv64x2)) 4095(rule (vecop_sdiv $I128) (VecBinaryOp.SDiv128)) 4096 4097(decl vec_sdiv (Type Reg Reg) Reg) 4098(rule (vec_sdiv ty x y) (vec_rrr ty (vecop_sdiv ty) x y)) 4099 4100(decl vecop_udiv (Type) VecBinaryOp) 4101(rule (vecop_udiv $I32X4) (VecBinaryOp.UDiv32x4)) 4102(rule (vecop_udiv $I64X2) (VecBinaryOp.UDiv64x2)) 4103(rule (vecop_udiv $I128) (VecBinaryOp.UDiv128)) 4104 4105(decl vec_udiv (Type Reg Reg) Reg) 4106(rule (vec_udiv ty x y) (vec_rrr ty (vecop_udiv ty) x y)) 4107 4108(decl vecop_srem (Type) VecBinaryOp) 4109(rule (vecop_srem $I32X4) (VecBinaryOp.SRem32x4)) 4110(rule (vecop_srem $I64X2) (VecBinaryOp.SRem64x2)) 4111(rule (vecop_srem $I128) (VecBinaryOp.SRem128)) 4112 4113(decl vec_srem (Type Reg Reg) Reg) 4114(rule (vec_srem ty x y) (vec_rrr ty (vecop_srem ty) x y)) 4115 4116(decl vecop_urem (Type) VecBinaryOp) 4117(rule (vecop_urem $I32X4) (VecBinaryOp.URem32x4)) 4118(rule (vecop_urem $I64X2) (VecBinaryOp.URem64x2)) 4119(rule (vecop_urem $I128) (VecBinaryOp.URem128)) 4120 4121(decl vec_urem (Type Reg Reg) Reg) 4122(rule (vec_urem ty x y) (vec_rrr ty (vecop_urem ty) x y)) 4123 4124 4125;; Helpers for generating `udivmod` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4126 4127(decl udivmod (Type RegPair Reg) RegPair) 4128(rule (udivmod $I32 x y) (udivmod32 x y)) 4129(rule (udivmod $I64 x y) (udivmod64 x y)) 4130 4131 4132;; Helpers for generating `sdivmod` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4133 4134(decl sdivmod (Type Reg Reg) RegPair) 4135(rule (sdivmod $I32 x y) (sdivmod32 x y)) 4136(rule (sdivmod $I64 x y) (sdivmod64 x y)) 4137 4138 4139;; Helpers for generating `umax` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4140 4141(decl vecop_umax (Type) VecBinaryOp) 4142(rule (vecop_umax $I8X16) (VecBinaryOp.UMax8x16)) 4143(rule (vecop_umax $I16X8) (VecBinaryOp.UMax16x8)) 4144(rule (vecop_umax $I32X4) (VecBinaryOp.UMax32x4)) 4145(rule (vecop_umax $I64X2) (VecBinaryOp.UMax64x2)) 4146(rule (vecop_umax $I128) (VecBinaryOp.UMax128)) 4147 4148(decl vec_umax (Type Reg Reg) Reg) 4149(rule (vec_umax ty x y) (vec_rrr ty (vecop_umax ty) x y)) 4150 4151 4152;; Helpers for generating `smax` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4153 4154(decl vecop_smax (Type) VecBinaryOp) 4155(rule (vecop_smax $I8X16) (VecBinaryOp.SMax8x16)) 4156(rule (vecop_smax $I16X8) (VecBinaryOp.SMax16x8)) 4157(rule (vecop_smax $I32X4) (VecBinaryOp.SMax32x4)) 4158(rule (vecop_smax $I64X2) (VecBinaryOp.SMax64x2)) 4159(rule (vecop_smax $I128) (VecBinaryOp.SMax128)) 4160 4161(decl vec_smax (Type Reg Reg) Reg) 4162(rule (vec_smax ty x y) (vec_rrr ty (vecop_smax ty) x y)) 4163 4164 4165;; Helpers for generating `umin` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4166 4167(decl vecop_umin (Type) VecBinaryOp) 4168(rule (vecop_umin $I8X16) (VecBinaryOp.UMin8x16)) 4169(rule (vecop_umin $I16X8) (VecBinaryOp.UMin16x8)) 4170(rule (vecop_umin $I32X4) (VecBinaryOp.UMin32x4)) 4171(rule (vecop_umin $I64X2) (VecBinaryOp.UMin64x2)) 4172(rule (vecop_umin $I128) (VecBinaryOp.UMin128)) 4173 4174(decl vec_umin (Type Reg Reg) Reg) 4175(rule (vec_umin ty x y) (vec_rrr ty (vecop_umin ty) x y)) 4176 4177 4178;; Helpers for generating `smin` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4179 4180(decl vecop_smin (Type) VecBinaryOp) 4181(rule (vecop_smin $I8X16) (VecBinaryOp.SMin8x16)) 4182(rule (vecop_smin $I16X8) (VecBinaryOp.SMin16x8)) 4183(rule (vecop_smin $I32X4) (VecBinaryOp.SMin32x4)) 4184(rule (vecop_smin $I64X2) (VecBinaryOp.SMin64x2)) 4185(rule (vecop_smin $I128) (VecBinaryOp.SMin128)) 4186 4187(decl vec_smin (Type Reg Reg) Reg) 4188(rule (vec_smin ty x y) (vec_rrr ty (vecop_smin ty) x y)) 4189 4190 4191;; Helpers for generating `avg_round` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4192 4193(decl vecop_uavg (Type) VecBinaryOp) 4194(rule (vecop_uavg $I8X16) (VecBinaryOp.UAvg8x16)) 4195(rule (vecop_uavg $I16X8) (VecBinaryOp.UAvg16x8)) 4196(rule (vecop_uavg $I32X4) (VecBinaryOp.UAvg32x4)) 4197(rule (vecop_uavg $I64X2) (VecBinaryOp.UAvg64x2)) 4198 4199(decl vec_uavg (Type Reg Reg) Reg) 4200(rule (vec_uavg ty x y) (vec_rrr ty (vecop_uavg ty) x y)) 4201 4202 4203;; Helpers for generating `and` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4204 4205(decl aluop_and (Type) ALUOp) 4206(rule (aluop_and (gpr32_ty _ty)) (ALUOp.And32)) 4207(rule 1 (aluop_and (gpr64_ty _ty)) (ALUOp.And64)) 4208 4209(decl and_reg (Type Reg Reg) Reg) 4210(rule (and_reg ty x y) (alu_rrr ty (aluop_and ty) x y)) 4211 4212(decl and_uimm16shifted (Type Reg UImm16Shifted) Reg) 4213(rule (and_uimm16shifted ty x y) (alu_ruimm16shifted ty (aluop_and ty) x y)) 4214 4215(decl and_uimm32shifted (Type Reg UImm32Shifted) Reg) 4216(rule (and_uimm32shifted ty x y) (alu_ruimm32shifted ty (aluop_and ty) x y)) 4217 4218(decl and_mem (Type Reg MemArg) Reg) 4219(rule (and_mem ty x y) (alu_rx ty (aluop_and ty) x y)) 4220 4221(decl vec_and (Type Reg Reg) Reg) 4222(rule (vec_and (vr128_ty ty) x y) (vec_rrr ty (VecBinaryOp.And128) x y)) 4223 4224 4225;; Helpers for generating `or` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4226 4227(decl aluop_or (Type) ALUOp) 4228(rule (aluop_or (gpr32_ty _ty)) (ALUOp.Orr32)) 4229(rule 1 (aluop_or (gpr64_ty _ty)) (ALUOp.Orr64)) 4230 4231(decl or_reg (Type Reg Reg) Reg) 4232(rule (or_reg ty x y) (alu_rrr ty (aluop_or ty) x y)) 4233 4234(decl or_uimm16shifted (Type Reg UImm16Shifted) Reg) 4235(rule (or_uimm16shifted ty x y) (alu_ruimm16shifted ty (aluop_or ty) x y)) 4236 4237(decl or_uimm32shifted (Type Reg UImm32Shifted) Reg) 4238(rule (or_uimm32shifted ty x y) (alu_ruimm32shifted ty (aluop_or ty) x y)) 4239 4240(decl or_mem (Type Reg MemArg) Reg) 4241(rule (or_mem ty x y) (alu_rx ty (aluop_or ty) x y)) 4242 4243(decl vec_or (Type Reg Reg) Reg) 4244(rule (vec_or (vr128_ty ty) x y) (vec_rrr ty (VecBinaryOp.Orr128) x y)) 4245 4246 4247;; Helpers for generating `xor` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4248 4249(decl aluop_xor (Type) ALUOp) 4250(rule (aluop_xor (gpr32_ty _ty)) (ALUOp.Xor32)) 4251(rule 1 (aluop_xor (gpr64_ty _ty)) (ALUOp.Xor64)) 4252 4253(decl xor_reg (Type Reg Reg) Reg) 4254(rule (xor_reg ty x y) (alu_rrr ty (aluop_xor ty) x y)) 4255 4256(decl xor_uimm32shifted (Type Reg UImm32Shifted) Reg) 4257(rule (xor_uimm32shifted ty x y) (alu_ruimm32shifted ty (aluop_xor ty) x y)) 4258 4259(decl xor_mem (Type Reg MemArg) Reg) 4260(rule (xor_mem ty x y) (alu_rx ty (aluop_xor ty) x y)) 4261 4262(decl push_xor_uimm32shifted (VecMInstBuilder Type WritableReg Reg UImm32Shifted) Reg) 4263(rule (push_xor_uimm32shifted ib ty dst src imm) 4264 (push_alu_uimm32shifted ib (aluop_xor ty) dst src imm)) 4265 4266(decl vec_xor (Type Reg Reg) Reg) 4267(rule (vec_xor (vr128_ty ty) x y) (vec_rrr ty (VecBinaryOp.Xor128) x y)) 4268 4269 4270;; Helpers for generating `not` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4271 4272(decl not_reg (Type Reg) Reg) 4273(rule (not_reg (gpr32_ty ty) x) 4274 (xor_uimm32shifted ty x (uimm32shifted 0xffffffff 0))) 4275(rule 1 (not_reg (gpr64_ty ty) x) 4276 (xor_uimm32shifted ty 4277 (xor_uimm32shifted ty x (uimm32shifted 0xffffffff 0)) 4278 (uimm32shifted 0xffffffff 32))) 4279 4280(decl push_not_reg (VecMInstBuilder Type WritableReg Reg) Reg) 4281(rule (push_not_reg ib (gpr32_ty ty) dst src) 4282 (push_xor_uimm32shifted ib ty dst src (uimm32shifted 0xffffffff 0))) 4283(rule 1 (push_not_reg ib (gpr64_ty ty) dst src) 4284 (let ((val Reg (push_xor_uimm32shifted ib ty dst src (uimm32shifted 0xffffffff 0)))) 4285 (push_xor_uimm32shifted ib ty dst val (uimm32shifted 0xffffffff 32)))) 4286 4287(decl vec_not (Type Reg) Reg) 4288(rule (vec_not ty x) (vec_not_or ty x x)) 4289 4290 4291;; Helpers for generating `not_and` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4292 4293(decl aluop_not_and (Type) ALUOp) 4294(rule (aluop_not_and (gpr32_ty _ty)) (ALUOp.NotAnd32)) 4295(rule 1 (aluop_not_and (gpr64_ty _ty)) (ALUOp.NotAnd64)) 4296 4297(decl not_and_reg (Type Reg Reg) Reg) 4298(rule (not_and_reg ty x y) (alu_rrr ty (aluop_not_and ty) x y)) 4299 4300(decl vec_not_and (Type Reg Reg) Reg) 4301(rule (vec_not_and (vr128_ty ty) x y) (vec_rrr ty (VecBinaryOp.NotAnd128) x y)) 4302 4303 4304;; Helpers for generating `not_or` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4305 4306(decl aluop_not_or (Type) ALUOp) 4307(rule (aluop_not_or (gpr32_ty _ty)) (ALUOp.NotOrr32)) 4308(rule 1 (aluop_not_or (gpr64_ty _ty)) (ALUOp.NotOrr64)) 4309 4310(decl not_or_reg (Type Reg Reg) Reg) 4311(rule (not_or_reg ty x y) (alu_rrr ty (aluop_not_or ty) x y)) 4312 4313(decl vec_not_or (Type Reg Reg) Reg) 4314(rule (vec_not_or (vr128_ty ty) x y) (vec_rrr ty (VecBinaryOp.NotOrr128) x y)) 4315 4316 4317;; Helpers for generating `not_xor` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4318 4319(decl aluop_not_xor (Type) ALUOp) 4320(rule (aluop_not_xor (gpr32_ty _ty)) (ALUOp.NotXor32)) 4321(rule 1 (aluop_not_xor (gpr64_ty _ty)) (ALUOp.NotXor64)) 4322 4323(decl not_xor_reg (Type Reg Reg) Reg) 4324(rule (not_xor_reg ty x y) (alu_rrr ty (aluop_not_xor ty) x y)) 4325 4326(decl vec_not_xor (Type Reg Reg) Reg) 4327(rule (vec_not_xor (vr128_ty ty) x y) (vec_rrr ty (VecBinaryOp.NotXor128) x y)) 4328 4329 4330;; Helpers for generating `and_not` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4331 4332(decl aluop_and_not (Type) ALUOp) 4333(rule (aluop_and_not (gpr32_ty _ty)) (ALUOp.AndNot32)) 4334(rule 1 (aluop_and_not (gpr64_ty _ty)) (ALUOp.AndNot64)) 4335 4336(decl and_not_reg (Type Reg Reg) Reg) 4337(rule (and_not_reg ty x y) (alu_rrr ty (aluop_and_not ty) x y)) 4338 4339(decl vec_and_not (Type Reg Reg) Reg) 4340(rule (vec_and_not (vr128_ty ty) x y) (vec_rrr ty (VecBinaryOp.AndNot128) x y)) 4341 4342 4343;; Helpers for generating `or_not` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4344 4345(decl aluop_or_not (Type) ALUOp) 4346(rule (aluop_or_not (gpr32_ty _ty)) (ALUOp.OrrNot32)) 4347(rule 1 (aluop_or_not (gpr64_ty _ty)) (ALUOp.OrrNot64)) 4348 4349(decl or_not_reg (Type Reg Reg) Reg) 4350(rule (or_not_reg ty x y) (alu_rrr ty (aluop_or_not ty) x y)) 4351 4352(decl vec_or_not (Type Reg Reg) Reg) 4353(rule (vec_or_not (vr128_ty ty) x y) (vec_rrr ty (VecBinaryOp.OrrNot128) x y)) 4354 4355 4356;; Helpers for generating `bitpermute` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4357 4358(decl vec_bitpermute (Reg Reg) Reg) 4359(rule (vec_bitpermute x y) (vec_rrr $I64X2 (VecBinaryOp.BitPermute128) x y)) 4360 4361 4362;; Helpers for generating `abs` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4363 4364(decl unaryop_abs (Type) UnaryOp) 4365(rule (unaryop_abs $I32) (UnaryOp.Abs32)) 4366(rule (unaryop_abs $I64) (UnaryOp.Abs64)) 4367 4368(decl unaryop_abs_sext32 (Type) UnaryOp) 4369(rule (unaryop_abs_sext32 $I64) (UnaryOp.Abs64Ext32)) 4370 4371(decl abs_reg (Type Reg) Reg) 4372(rule (abs_reg ty x) (unary_rr ty (unaryop_abs ty) x)) 4373 4374(decl abs_reg_sext32 (Type Reg) Reg) 4375(rule (abs_reg_sext32 ty x) (unary_rr ty (unaryop_abs_sext32 ty) x)) 4376 4377(decl vecop_abs (Type) VecUnaryOp) 4378(rule (vecop_abs $I8X16) (VecUnaryOp.Abs8x16)) 4379(rule (vecop_abs $I16X8) (VecUnaryOp.Abs16x8)) 4380(rule (vecop_abs $I32X4) (VecUnaryOp.Abs32x4)) 4381(rule (vecop_abs $I64X2) (VecUnaryOp.Abs64x2)) 4382(rule (vecop_abs $I128) (VecUnaryOp.Abs128)) 4383 4384(decl vec_abs (Type Reg) Reg) 4385(rule (vec_abs ty x) (vec_rr ty (vecop_abs ty) x)) 4386 4387 4388;; Helpers for generating `neg` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4389 4390(decl unaryop_neg (Type) UnaryOp) 4391(rule (unaryop_neg $I8) (UnaryOp.Neg32)) 4392(rule (unaryop_neg $I16) (UnaryOp.Neg32)) 4393(rule (unaryop_neg $I32) (UnaryOp.Neg32)) 4394(rule (unaryop_neg $I64) (UnaryOp.Neg64)) 4395 4396(decl unaryop_neg_sext32 (Type) UnaryOp) 4397(rule (unaryop_neg_sext32 $I64) (UnaryOp.Neg64Ext32)) 4398 4399(decl neg_reg (Type Reg) Reg) 4400(rule (neg_reg ty x) (unary_rr ty (unaryop_neg ty) x)) 4401 4402(decl neg_reg_sext32 (Type Reg) Reg) 4403(rule (neg_reg_sext32 ty x) (unary_rr ty (unaryop_neg_sext32 ty) x)) 4404 4405(decl vecop_neg (Type) VecUnaryOp) 4406(rule (vecop_neg $I8X16) (VecUnaryOp.Neg8x16)) 4407(rule (vecop_neg $I16X8) (VecUnaryOp.Neg16x8)) 4408(rule (vecop_neg $I32X4) (VecUnaryOp.Neg32x4)) 4409(rule (vecop_neg $I64X2) (VecUnaryOp.Neg64x2)) 4410(rule (vecop_neg $I128) (VecUnaryOp.Neg128)) 4411 4412(decl vec_neg (Type Reg) Reg) 4413(rule (vec_neg ty x) (vec_rr ty (vecop_neg ty) x)) 4414 4415 4416;; Helpers for generating `bswap` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4417 4418(decl unaryop_bswap (Type) UnaryOp) 4419(rule (unaryop_bswap $I32) (UnaryOp.BSwap32)) 4420(rule (unaryop_bswap $I64) (UnaryOp.BSwap64)) 4421 4422(decl bswap_reg (Type Reg) Reg) 4423(rule (bswap_reg ty x) (unary_rr ty (unaryop_bswap ty) x)) 4424 4425(decl push_bswap_reg (VecMInstBuilder Type WritableReg Reg) Reg) 4426(rule (push_bswap_reg ib ty dst src) (push_unary ib (unaryop_bswap ty) dst src)) 4427 4428 4429;; Helpers for generating `rot` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4430 4431(decl shiftop_rot (Type) ShiftOp) 4432(rule (shiftop_rot $I32) (ShiftOp.RotL32)) 4433(rule (shiftop_rot $I64) (ShiftOp.RotL64)) 4434 4435(decl rot_reg (Type Reg Reg) Reg) 4436(rule (rot_reg ty x shift_reg) 4437 (shift_rr ty (shiftop_rot ty) x 0 shift_reg)) 4438 4439(decl rot_imm (Type Reg u8) Reg) 4440(rule (rot_imm ty x shift_imm) 4441 (shift_rr ty (shiftop_rot ty) x shift_imm (zero_reg))) 4442 4443(decl rot_imm_reg (Type Reg u8 Reg) Reg) 4444(rule (rot_imm_reg ty x shift_imm shift_reg) 4445 (shift_rr ty (shiftop_rot ty) x shift_imm shift_reg)) 4446 4447(decl push_rot_imm_reg (VecMInstBuilder Type WritableReg Reg u8 Reg) Reg) 4448(rule (push_rot_imm_reg ib ty dst src shift_imm shift_reg) 4449 (push_shift ib (shiftop_rot ty) dst src shift_imm shift_reg)) 4450 4451(decl vec_shiftop_rot (Type) VecShiftOp) 4452(rule (vec_shiftop_rot $I8X16) (VecShiftOp.RotL8x16)) 4453(rule (vec_shiftop_rot $I16X8) (VecShiftOp.RotL16x8)) 4454(rule (vec_shiftop_rot $I32X4) (VecShiftOp.RotL32x4)) 4455(rule (vec_shiftop_rot $I64X2) (VecShiftOp.RotL64x2)) 4456 4457(decl vec_rot_reg (Type Reg Reg) Reg) 4458(rule (vec_rot_reg ty x shift_reg) 4459 (vec_shift_rr ty (vec_shiftop_rot ty) x 0 shift_reg)) 4460 4461(decl vec_rot_imm (Type Reg u8) Reg) 4462(rule (vec_rot_imm ty x shift_imm) 4463 (vec_shift_rr ty (vec_shiftop_rot ty) x shift_imm (zero_reg))) 4464 4465 4466;; Helpers for generating `lshl` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4467 4468(decl shiftop_lshl (Type) ShiftOp) 4469(rule (shiftop_lshl $I8) (ShiftOp.LShL32)) 4470(rule (shiftop_lshl $I16) (ShiftOp.LShL32)) 4471(rule (shiftop_lshl $I32) (ShiftOp.LShL32)) 4472(rule (shiftop_lshl $I64) (ShiftOp.LShL64)) 4473 4474(decl lshl_reg (Type Reg Reg) Reg) 4475(rule (lshl_reg ty x shift_reg) 4476 (shift_rr ty (shiftop_lshl ty) x 0 shift_reg)) 4477 4478(decl lshl_imm (Type Reg u8) Reg) 4479(rule (lshl_imm ty x shift_imm) 4480 (shift_rr ty (shiftop_lshl ty) x shift_imm (zero_reg))) 4481 4482(decl vec_shiftop_lshl (Type) VecShiftOp) 4483(rule (vec_shiftop_lshl $I8X16) (VecShiftOp.LShL8x16)) 4484(rule (vec_shiftop_lshl $I16X8) (VecShiftOp.LShL16x8)) 4485(rule (vec_shiftop_lshl $I32X4) (VecShiftOp.LShL32x4)) 4486(rule (vec_shiftop_lshl $I64X2) (VecShiftOp.LShL64x2)) 4487 4488(decl vec_lshl_reg (Type Reg Reg) Reg) 4489(rule (vec_lshl_reg ty x shift_reg) 4490 (vec_shift_rr ty (vec_shiftop_lshl ty) x 0 shift_reg)) 4491 4492(decl vec_lshl_imm (Type Reg u8) Reg) 4493(rule (vec_lshl_imm ty x shift_imm) 4494 (vec_shift_rr ty (vec_shiftop_lshl ty) x shift_imm (zero_reg))) 4495 4496(decl vec_lshl_by_byte (Reg Reg) Reg) 4497(rule (vec_lshl_by_byte x y) (vec_rrr $I8X16 (VecBinaryOp.LShLByByte128) x y)) 4498 4499(decl vec_lshl_by_bit (Reg Reg) Reg) 4500(rule (vec_lshl_by_bit x y) (vec_rrr $I8X16 (VecBinaryOp.LShLByBit128) x y)) 4501 4502 4503;; Helpers for generating `lshr` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4504 4505(decl shiftop_lshr (Type) ShiftOp) 4506(rule (shiftop_lshr $I32) (ShiftOp.LShR32)) 4507(rule (shiftop_lshr $I64) (ShiftOp.LShR64)) 4508 4509(decl lshr_reg (Type Reg Reg) Reg) 4510(rule (lshr_reg ty x shift_reg) 4511 (shift_rr ty (shiftop_lshr ty) x 0 shift_reg)) 4512 4513(decl lshr_imm (Type Reg u8) Reg) 4514(rule (lshr_imm ty x shift_imm) 4515 (shift_rr ty (shiftop_lshr ty) x shift_imm (zero_reg))) 4516 4517(decl vec_shiftop_lshr (Type) VecShiftOp) 4518(rule (vec_shiftop_lshr $I8X16) (VecShiftOp.LShR8x16)) 4519(rule (vec_shiftop_lshr $I16X8) (VecShiftOp.LShR16x8)) 4520(rule (vec_shiftop_lshr $I32X4) (VecShiftOp.LShR32x4)) 4521(rule (vec_shiftop_lshr $I64X2) (VecShiftOp.LShR64x2)) 4522 4523(decl vec_lshr_reg (Type Reg Reg) Reg) 4524(rule (vec_lshr_reg ty x shift_reg) 4525 (vec_shift_rr ty (vec_shiftop_lshr ty) x 0 shift_reg)) 4526 4527(decl vec_lshr_imm (Type Reg u8) Reg) 4528(rule (vec_lshr_imm ty x shift_imm) 4529 (vec_shift_rr ty (vec_shiftop_lshr ty) x shift_imm (zero_reg))) 4530 4531(decl vec_lshr_by_byte (Reg Reg) Reg) 4532(rule (vec_lshr_by_byte x y) (vec_rrr $I8X16 (VecBinaryOp.LShRByByte128) x y)) 4533 4534(decl vec_lshr_by_bit (Reg Reg) Reg) 4535(rule (vec_lshr_by_bit x y) (vec_rrr $I8X16 (VecBinaryOp.LShRByBit128) x y)) 4536 4537 4538;; Helpers for generating `ashr` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4539 4540(decl shiftop_ashr (Type) ShiftOp) 4541(rule (shiftop_ashr $I32) (ShiftOp.AShR32)) 4542(rule (shiftop_ashr $I64) (ShiftOp.AShR64)) 4543 4544(decl ashr_reg (Type Reg Reg) Reg) 4545(rule (ashr_reg ty x shift_reg) 4546 (shift_rr ty (shiftop_ashr ty) x 0 shift_reg)) 4547 4548(decl ashr_imm (Type Reg u8) Reg) 4549(rule (ashr_imm ty x shift_imm) 4550 (shift_rr ty (shiftop_ashr ty) x shift_imm (zero_reg))) 4551 4552(decl vec_shiftop_ashr (Type) VecShiftOp) 4553(rule (vec_shiftop_ashr $I8X16) (VecShiftOp.AShR8x16)) 4554(rule (vec_shiftop_ashr $I16X8) (VecShiftOp.AShR16x8)) 4555(rule (vec_shiftop_ashr $I32X4) (VecShiftOp.AShR32x4)) 4556(rule (vec_shiftop_ashr $I64X2) (VecShiftOp.AShR64x2)) 4557 4558(decl vec_ashr_reg (Type Reg Reg) Reg) 4559(rule (vec_ashr_reg ty x shift_reg) 4560 (vec_shift_rr ty (vec_shiftop_ashr ty) x 0 shift_reg)) 4561 4562(decl vec_ashr_imm (Type Reg u8) Reg) 4563(rule (vec_ashr_imm ty x shift_imm) 4564 (vec_shift_rr ty (vec_shiftop_ashr ty) x shift_imm (zero_reg))) 4565 4566(decl vec_ashr_by_byte (Reg Reg) Reg) 4567(rule (vec_ashr_by_byte x y) (vec_rrr $I8X16 (VecBinaryOp.AShRByByte128) x y)) 4568 4569(decl vec_ashr_by_bit (Reg Reg) Reg) 4570(rule (vec_ashr_by_bit x y) (vec_rrr $I8X16 (VecBinaryOp.AShRByBit128) x y)) 4571 4572 4573;; Helpers for generating `popcnt` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4574 4575(decl popcnt_byte (Reg) Reg) 4576(rule (popcnt_byte x) (unary_rr $I64 (UnaryOp.PopcntByte) x)) 4577 4578(decl popcnt_reg (Reg) Reg) 4579(rule (popcnt_reg x) (unary_rr $I64 (UnaryOp.PopcntReg) x)) 4580 4581(decl vecop_popcnt (Type) VecUnaryOp) 4582(rule (vecop_popcnt $I8X16) (VecUnaryOp.Popcnt8x16)) 4583(rule (vecop_popcnt $I16X8) (VecUnaryOp.Popcnt16x8)) 4584(rule (vecop_popcnt $I32X4) (VecUnaryOp.Popcnt32x4)) 4585(rule (vecop_popcnt $I64X2) (VecUnaryOp.Popcnt64x2)) 4586 4587(decl vec_popcnt (Type Reg) Reg) 4588(rule (vec_popcnt ty x) (vec_rr ty (vecop_popcnt ty) x)) 4589 4590 4591;; Helpers for generating `atomic_rmw` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4592 4593(decl atomic_rmw_and (Type Reg MemArg) Reg) 4594(rule (atomic_rmw_and $I32 src mem) (atomic_rmw_impl $I32 (ALUOp.And32) src mem)) 4595(rule (atomic_rmw_and $I64 src mem) (atomic_rmw_impl $I64 (ALUOp.And64) src mem)) 4596 4597(decl atomic_rmw_or (Type Reg MemArg) Reg) 4598(rule (atomic_rmw_or $I32 src mem) (atomic_rmw_impl $I32 (ALUOp.Orr32) src mem)) 4599(rule (atomic_rmw_or $I64 src mem) (atomic_rmw_impl $I64 (ALUOp.Orr64) src mem)) 4600 4601(decl atomic_rmw_xor (Type Reg MemArg) Reg) 4602(rule (atomic_rmw_xor $I32 src mem) (atomic_rmw_impl $I32 (ALUOp.Xor32) src mem)) 4603(rule (atomic_rmw_xor $I64 src mem) (atomic_rmw_impl $I64 (ALUOp.Xor64) src mem)) 4604 4605(decl atomic_rmw_add (Type Reg MemArg) Reg) 4606(rule (atomic_rmw_add $I32 src mem) (atomic_rmw_impl $I32 (ALUOp.Add32) src mem)) 4607(rule (atomic_rmw_add $I64 src mem) (atomic_rmw_impl $I64 (ALUOp.Add64) src mem)) 4608 4609 4610;; Helpers for generating `atomic_cas` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4611 4612(decl atomic_cas_impl (Type Reg Reg MemArg) Reg) 4613(rule (atomic_cas_impl $I32 src1 src2 mem) (atomic_cas32 src1 src2 mem)) 4614(rule (atomic_cas_impl $I64 src1 src2 mem) (atomic_cas64 src1 src2 mem)) 4615 4616(decl push_atomic_cas (VecMInstBuilder Type WritableReg Reg MemArg) Reg) 4617(rule (push_atomic_cas ib $I32 src1 src2 mem) (push_atomic_cas32 ib src1 src2 mem)) 4618(rule (push_atomic_cas ib $I64 src1 src2 mem) (push_atomic_cas64 ib src1 src2 mem)) 4619 4620 4621;; Helpers for generating `fadd` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4622 4623(decl fpuop2_add (Type) FPUOp2) 4624(rule (fpuop2_add $F32) (FPUOp2.Add32)) 4625(rule (fpuop2_add $F64) (FPUOp2.Add64)) 4626(rule (fpuop2_add $F128) (FPUOp2.Add128)) 4627(rule (fpuop2_add $F32X4) (FPUOp2.Add32x4)) 4628(rule (fpuop2_add $F64X2) (FPUOp2.Add64x2)) 4629 4630(decl fadd_reg (Type Reg Reg) Reg) 4631(rule (fadd_reg ty x y) (fpu_rrr ty (fpuop2_add ty) x y)) 4632 4633 4634;; Helpers for generating `fsub` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4635 4636(decl fpuop2_sub (Type) FPUOp2) 4637(rule (fpuop2_sub $F32) (FPUOp2.Sub32)) 4638(rule (fpuop2_sub $F64) (FPUOp2.Sub64)) 4639(rule (fpuop2_sub $F128) (FPUOp2.Sub128)) 4640(rule (fpuop2_sub $F32X4) (FPUOp2.Sub32x4)) 4641(rule (fpuop2_sub $F64X2) (FPUOp2.Sub64x2)) 4642 4643(decl fsub_reg (Type Reg Reg) Reg) 4644(rule (fsub_reg ty x y) (fpu_rrr ty (fpuop2_sub ty) x y)) 4645 4646 4647;; Helpers for generating `fmul` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4648 4649(decl fpuop2_mul (Type) FPUOp2) 4650(rule (fpuop2_mul $F32) (FPUOp2.Mul32)) 4651(rule (fpuop2_mul $F64) (FPUOp2.Mul64)) 4652(rule (fpuop2_mul $F128) (FPUOp2.Mul128)) 4653(rule (fpuop2_mul $F32X4) (FPUOp2.Mul32x4)) 4654(rule (fpuop2_mul $F64X2) (FPUOp2.Mul64x2)) 4655 4656(decl fmul_reg (Type Reg Reg) Reg) 4657(rule (fmul_reg ty x y) (fpu_rrr ty (fpuop2_mul ty) x y)) 4658 4659 4660;; Helpers for generating `fdiv` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4661 4662(decl fpuop2_div (Type) FPUOp2) 4663(rule (fpuop2_div $F32) (FPUOp2.Div32)) 4664(rule (fpuop2_div $F64) (FPUOp2.Div64)) 4665(rule (fpuop2_div $F128) (FPUOp2.Div128)) 4666(rule (fpuop2_div $F32X4) (FPUOp2.Div32x4)) 4667(rule (fpuop2_div $F64X2) (FPUOp2.Div64x2)) 4668 4669(decl fdiv_reg (Type Reg Reg) Reg) 4670(rule (fdiv_reg ty x y) (fpu_rrr ty (fpuop2_div ty) x y)) 4671 4672 4673;; Helpers for generating `fmin` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4674 4675(decl fpuop2_min (Type) FPUOp2) 4676(rule (fpuop2_min $F32) (FPUOp2.Min32)) 4677(rule (fpuop2_min $F64) (FPUOp2.Min64)) 4678(rule (fpuop2_min $F128) (FPUOp2.Min128)) 4679(rule (fpuop2_min $F32X4) (FPUOp2.Min32x4)) 4680(rule (fpuop2_min $F64X2) (FPUOp2.Min64x2)) 4681 4682(decl fmin_reg (Type Reg Reg) Reg) 4683(rule (fmin_reg ty x y) (fpu_rrr ty (fpuop2_min ty) x y)) 4684 4685 4686;; Helpers for generating `fmax` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4687 4688(decl fpuop2_max (Type) FPUOp2) 4689(rule (fpuop2_max $F32) (FPUOp2.Max32)) 4690(rule (fpuop2_max $F64) (FPUOp2.Max64)) 4691(rule (fpuop2_max $F128) (FPUOp2.Max128)) 4692(rule (fpuop2_max $F32X4) (FPUOp2.Max32x4)) 4693(rule (fpuop2_max $F64X2) (FPUOp2.Max64x2)) 4694 4695(decl fmax_reg (Type Reg Reg) Reg) 4696(rule (fmax_reg ty x y) (fpu_rrr ty (fpuop2_max ty) x y)) 4697 4698 4699;; Helpers for generating `fmin_pseudo` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;; 4700 4701(decl fpuop2_min_pseudo (Type) FPUOp2) 4702(rule (fpuop2_min_pseudo $F32) (FPUOp2.MinPseudo32)) 4703(rule (fpuop2_min_pseudo $F64) (FPUOp2.MinPseudo64)) 4704(rule (fpuop2_min_pseudo $F128) (FPUOp2.MinPseudo128)) 4705(rule (fpuop2_min_pseudo $F32X4) (FPUOp2.MinPseudo32x4)) 4706(rule (fpuop2_min_pseudo $F64X2) (FPUOp2.MinPseudo64x2)) 4707 4708(decl fmin_pseudo_reg (Type Reg Reg) Reg) 4709(rule (fmin_pseudo_reg ty x y) (fpu_rrr ty (fpuop2_min_pseudo ty) x y)) 4710 4711 4712;; Helpers for generating `fmax_pseudo` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;; 4713 4714(decl fpuop2_max_pseudo (Type) FPUOp2) 4715(rule (fpuop2_max_pseudo $F32) (FPUOp2.MaxPseudo32)) 4716(rule (fpuop2_max_pseudo $F64) (FPUOp2.MaxPseudo64)) 4717(rule (fpuop2_max_pseudo $F128) (FPUOp2.MaxPseudo128)) 4718(rule (fpuop2_max_pseudo $F32X4) (FPUOp2.MaxPseudo32x4)) 4719(rule (fpuop2_max_pseudo $F64X2) (FPUOp2.MaxPseudo64x2)) 4720 4721(decl fmax_pseudo_reg (Type Reg Reg) Reg) 4722(rule (fmax_pseudo_reg ty x y) (fpu_rrr ty (fpuop2_max_pseudo ty) x y)) 4723 4724 4725;; Helpers for generating `fma` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4726 4727(decl fpuop3_fma (Type) FPUOp3) 4728(rule (fpuop3_fma $F32) (FPUOp3.MAdd32)) 4729(rule (fpuop3_fma $F64) (FPUOp3.MAdd64)) 4730(rule (fpuop3_fma $F128) (FPUOp3.MAdd128)) 4731(rule (fpuop3_fma $F32X4) (FPUOp3.MAdd32x4)) 4732(rule (fpuop3_fma $F64X2) (FPUOp3.MAdd64x2)) 4733 4734(decl fma_reg (Type Reg Reg Reg) Reg) 4735(rule (fma_reg ty x y acc) (fpu_rrrr ty (fpuop3_fma ty) x y acc)) 4736 4737 4738;; Helpers for generating `sqrt` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4739 4740(decl fpuop1_sqrt (Type) FPUOp1) 4741(rule (fpuop1_sqrt $F32) (FPUOp1.Sqrt32)) 4742(rule (fpuop1_sqrt $F64) (FPUOp1.Sqrt64)) 4743(rule (fpuop1_sqrt $F128) (FPUOp1.Sqrt128)) 4744(rule (fpuop1_sqrt $F32X4) (FPUOp1.Sqrt32x4)) 4745(rule (fpuop1_sqrt $F64X2) (FPUOp1.Sqrt64x2)) 4746 4747(decl sqrt_reg (Type Reg) Reg) 4748(rule (sqrt_reg ty x) (fpu_rr ty (fpuop1_sqrt ty) x)) 4749 4750 4751;; Helpers for generating `fneg` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4752 4753(decl fpuop1_neg (Type) FPUOp1) 4754(rule (fpuop1_neg $F32) (FPUOp1.Neg32)) 4755(rule (fpuop1_neg $F64) (FPUOp1.Neg64)) 4756(rule (fpuop1_neg $F128) (FPUOp1.Neg128)) 4757(rule (fpuop1_neg $F32X4) (FPUOp1.Neg32x4)) 4758(rule (fpuop1_neg $F64X2) (FPUOp1.Neg64x2)) 4759 4760(decl fneg_reg (Type Reg) Reg) 4761(rule (fneg_reg ty x) (fpu_rr ty (fpuop1_neg ty) x)) 4762 4763 4764;; Helpers for generating `fabs` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4765 4766(decl fpuop1_abs (Type) FPUOp1) 4767(rule (fpuop1_abs $F32) (FPUOp1.Abs32)) 4768(rule (fpuop1_abs $F64) (FPUOp1.Abs64)) 4769(rule (fpuop1_abs $F128) (FPUOp1.Abs128)) 4770(rule (fpuop1_abs $F32X4) (FPUOp1.Abs32x4)) 4771(rule (fpuop1_abs $F64X2) (FPUOp1.Abs64x2)) 4772 4773(decl fabs_reg (Type Reg) Reg) 4774(rule (fabs_reg ty x) (fpu_rr ty (fpuop1_abs ty) x)) 4775 4776 4777;; Helpers for generating `ceil`, `floor`, `trunc`, `nearest` instructions ;;;; 4778 4779(decl fpuroundop_round (Type) FpuRoundOp) 4780(rule (fpuroundop_round $F32) (FpuRoundOp.Round32)) 4781(rule (fpuroundop_round $F64) (FpuRoundOp.Round64)) 4782(rule (fpuroundop_round $F128) (FpuRoundOp.Round128)) 4783(rule (fpuroundop_round $F32X4) (FpuRoundOp.Round32x4)) 4784(rule (fpuroundop_round $F64X2) (FpuRoundOp.Round64x2)) 4785 4786(decl ceil_reg (Type Reg) Reg) 4787(rule (ceil_reg ty x) (fpu_round ty (fpuroundop_round ty) 4788 (FpuRoundMode.ToPosInfinity) x)) 4789 4790(decl floor_reg (Type Reg) Reg) 4791(rule (floor_reg ty x) (fpu_round ty (fpuroundop_round ty) 4792 (FpuRoundMode.ToNegInfinity) x)) 4793 4794(decl trunc_reg (Type Reg) Reg) 4795(rule (trunc_reg ty x) (fpu_round ty (fpuroundop_round ty) 4796 (FpuRoundMode.ToZero) x)) 4797 4798(decl nearest_reg (Type Reg) Reg) 4799(rule (nearest_reg ty x) (fpu_round ty (fpuroundop_round ty) 4800 (FpuRoundMode.ToNearestTiesToEven) x)) 4801 4802 4803;; Helpers for generating `fpromote` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4804 4805(decl fpromote_reg (Type Type Reg) Reg) 4806(rule 1 (fpromote_reg ty ty x) x) 4807(rule (fpromote_reg $F64 $F32 x) 4808 (fpu_rr $F64 (FPUOp1.Cvt32To64) x)) 4809(rule (fpromote_reg $F64X2 $F32X4 x) 4810 (fpu_rr $F64 (FPUOp1.Cvt32x4To64x2) x)) 4811(rule (fpromote_reg $F128 $F64 x) 4812 (fpu_rr $F128 (FPUOp1.Cvt64To128) x)) 4813 4814 4815;; Helpers for generating `fdemote` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 4816 4817(decl fdemote_reg (Type Type FpuRoundMode Reg) Reg) 4818(rule 1 (fdemote_reg ty ty mode x) x) 4819(rule (fdemote_reg $F32 $F64 mode x) 4820 (fpu_round $F32 (FpuRoundOp.Cvt64To32) mode x)) 4821(rule (fdemote_reg $F32X4 $F64X2 mode x) 4822 (fpu_round $F32X4 (FpuRoundOp.Cvt64x2To32x4) mode x)) 4823(rule (fdemote_reg $F64 $F128 mode x) 4824 (fpu_round $F64 (FpuRoundOp.Cvt128To64) mode x)) 4825 4826 4827;; Helpers for generating `fcvt_from_uint` instructions ;;;;;;;;;;;;;;;;;;;;;;;; 4828 4829(decl fcvt_from_uint_reg (Type Type FpuRoundMode Reg) Reg) 4830(rule (fcvt_from_uint_reg $F32 $I32 mode x) 4831 (fpu_round $F32 (FpuRoundOp.FromUInt32) mode (vec_insert_lane_undef $I32X4 x 0 (zero_reg)))) 4832(rule (fcvt_from_uint_reg $F64 $I64 mode x) 4833 (fpu_round $F64 (FpuRoundOp.FromUInt64) mode (vec_insert_lane_undef $I64X2 x 0 (zero_reg)))) 4834(rule (fcvt_from_uint_reg $F32X4 $I32X4 mode x) 4835 (fpu_round $F32X4 (FpuRoundOp.FromUInt32x4) mode x)) 4836(rule (fcvt_from_uint_reg $F64X2 $I64X2 mode x) 4837 (fpu_round $F64X2 (FpuRoundOp.FromUInt64x2) mode x)) 4838(rule (fcvt_from_uint_reg $F128 $I32 mode x) 4839 (fp_regpair_to_reg (fpu_conv128_from_int (FpuConv128Op.UInt32) mode x))) 4840(rule (fcvt_from_uint_reg $F128 $I64 mode x) 4841 (fp_regpair_to_reg (fpu_conv128_from_int (FpuConv128Op.UInt64) mode x))) 4842 4843 4844;; Helpers for generating `fcvt_from_sint` instructions ;;;;;;;;;;;;;;;;;;;;;;;; 4845 4846(decl fcvt_from_sint_reg (Type Type FpuRoundMode Reg) Reg) 4847(rule (fcvt_from_sint_reg $F32 $I32 mode x) 4848 (fpu_round $F32 (FpuRoundOp.FromSInt32) mode (vec_insert_lane_undef $I32X4 x 0 (zero_reg)))) 4849(rule (fcvt_from_sint_reg $F64 $I64 mode x) 4850 (fpu_round $F64 (FpuRoundOp.FromSInt64) mode (vec_insert_lane_undef $I64X2 x 0 (zero_reg)))) 4851(rule (fcvt_from_sint_reg $F32X4 $I32X4 mode x) 4852 (fpu_round $F32X4 (FpuRoundOp.FromSInt32x4) mode x)) 4853(rule (fcvt_from_sint_reg $F64X2 $I64X2 mode x) 4854 (fpu_round $F64X2 (FpuRoundOp.FromSInt64x2) mode x)) 4855(rule (fcvt_from_sint_reg $F128 $I32 mode x) 4856 (fp_regpair_to_reg (fpu_conv128_from_int (FpuConv128Op.SInt32) mode x))) 4857(rule (fcvt_from_sint_reg $F128 $I64 mode x) 4858 (fp_regpair_to_reg (fpu_conv128_from_int (FpuConv128Op.SInt64) mode x))) 4859 4860 4861;; Helpers for generating `fcvt_to_[us]int` instructions ;;;;;;;;;;;;;;;;;;;;;;; 4862 4863(decl fcvt_flt_ty (Type Type) Type) 4864(rule 1 (fcvt_flt_ty (fits_in_32 ty) (and (vxrs_ext2_enabled) $F32)) $F32) 4865(rule (fcvt_flt_ty (fits_in_64 ty) $F32) $F64) 4866(rule (fcvt_flt_ty (fits_in_64 ty) $F64) $F64) 4867(rule (fcvt_flt_ty (fits_in_64 ty) $F128) $F128) 4868 4869(decl fcvt_int_ty (Type Type) Type) 4870(rule 1 (fcvt_int_ty (fits_in_32 ty) (and (vxrs_ext2_enabled) $F32)) $I32) 4871(rule (fcvt_int_ty (fits_in_64 ty) $F32) $I64) 4872(rule (fcvt_int_ty (fits_in_64 ty) $F64) $I64) 4873(rule 1 (fcvt_int_ty (fits_in_32 ty) $F128) $I32) 4874(rule (fcvt_int_ty (fits_in_64 ty) $F128) $I64) 4875 4876 4877;; Helpers for generating `fcvt_to_uint` instructions ;;;;;;;;;;;;;;;;;;;;;;;; 4878 4879(decl fcvt_to_uint_reg (Type Type FpuRoundMode Reg) Reg) 4880(rule (fcvt_to_uint_reg $I32 $F32 mode x) 4881 (vec_extract_lane $I32X4 (fpu_round $F32 (FpuRoundOp.ToUInt32) mode x) 0 (zero_reg))) 4882(rule (fcvt_to_uint_reg $I64 $F64 mode x) 4883 (vec_extract_lane $I64X2 (fpu_round $F64 (FpuRoundOp.ToUInt64) mode x) 0 (zero_reg))) 4884(rule (fcvt_to_uint_reg $I32X4 $F32X4 mode x) 4885 (fpu_round $F32X4 (FpuRoundOp.ToUInt32x4) mode x)) 4886(rule (fcvt_to_uint_reg $I64X2 $F64X2 mode x) 4887 (fpu_round $F64X2 (FpuRoundOp.ToUInt64x2) mode x)) 4888(rule (fcvt_to_uint_reg $I32 $F128 mode x) 4889 (fpu_conv128_to_int $I32 (FpuConv128Op.UInt32) mode (fp_reg_to_regpair x))) 4890(rule (fcvt_to_uint_reg $I64 $F128 mode x) 4891 (fpu_conv128_to_int $I64 (FpuConv128Op.UInt64) mode (fp_reg_to_regpair x))) 4892 4893(decl fcvt_to_uint_ub (Type Type) Reg) 4894(rule (fcvt_to_uint_ub $F32 dst_ty) 4895 (imm $F32 (fcvt_to_uint_ub32 (ty_bits dst_ty)))) 4896(rule (fcvt_to_uint_ub $F64 dst_ty) 4897 (imm $F64 (fcvt_to_uint_ub64 (ty_bits dst_ty)))) 4898(rule (fcvt_to_uint_ub $F128 dst_ty) 4899 (vec_imm $F128 (fcvt_to_uint_ub128 (ty_bits dst_ty)))) 4900 4901(decl fcvt_to_uint_lb (Type) Reg) 4902(rule (fcvt_to_uint_lb $F32) (imm $F32 (fcvt_to_uint_lb32))) 4903(rule (fcvt_to_uint_lb $F64) (imm $F64 (fcvt_to_uint_lb64))) 4904(rule (fcvt_to_uint_lb $F128) (vec_imm $F128 (fcvt_to_uint_lb128))) 4905 4906(decl fcvt_to_uint_ub32 (u8) u64) 4907(extern constructor fcvt_to_uint_ub32 fcvt_to_uint_ub32) 4908(decl fcvt_to_uint_lb32 () u64) 4909(extern constructor fcvt_to_uint_lb32 fcvt_to_uint_lb32) 4910(decl fcvt_to_uint_ub64 (u8) u64) 4911(extern constructor fcvt_to_uint_ub64 fcvt_to_uint_ub64) 4912(decl fcvt_to_uint_lb64 () u64) 4913(extern constructor fcvt_to_uint_lb64 fcvt_to_uint_lb64) 4914(decl fcvt_to_uint_ub128 (u8) u128) 4915(extern constructor fcvt_to_uint_ub128 fcvt_to_uint_ub128) 4916(decl fcvt_to_uint_lb128 () u128) 4917(extern constructor fcvt_to_uint_lb128 fcvt_to_uint_lb128) 4918 4919 4920;; Helpers for generating `fcvt_to_sint` instructions ;;;;;;;;;;;;;;;;;;;;;;;; 4921 4922(decl fcvt_to_sint_reg (Type Type FpuRoundMode Reg) Reg) 4923(rule (fcvt_to_sint_reg $I32 $F32 mode x) 4924 (vec_extract_lane $F32X4 (fpu_round $F32 (FpuRoundOp.ToSInt32) mode x) 0 (zero_reg))) 4925(rule (fcvt_to_sint_reg $I64 $F64 mode x) 4926 (vec_extract_lane $F64X2 (fpu_round $F64 (FpuRoundOp.ToSInt64) mode x) 0 (zero_reg))) 4927(rule (fcvt_to_sint_reg $I32X4 $F32X4 mode x) 4928 (fpu_round $F32X4 (FpuRoundOp.ToSInt32x4) mode x)) 4929(rule (fcvt_to_sint_reg $I64X2 $F64X2 mode x) 4930 (fpu_round $F64X2 (FpuRoundOp.ToSInt64x2) mode x)) 4931(rule (fcvt_to_sint_reg $I32 $F128 mode x) 4932 (fpu_conv128_to_int $I32 (FpuConv128Op.SInt32) mode (fp_reg_to_regpair x))) 4933(rule (fcvt_to_sint_reg $I64 $F128 mode x) 4934 (fpu_conv128_to_int $I64 (FpuConv128Op.SInt64) mode (fp_reg_to_regpair x))) 4935 4936(decl fcvt_to_sint_ub (Type Type) Reg) 4937(rule (fcvt_to_sint_ub $F32 dst_ty) 4938 (imm $F32 (fcvt_to_sint_ub32 (ty_bits dst_ty)))) 4939(rule (fcvt_to_sint_ub $F64 dst_ty) 4940 (imm $F64 (fcvt_to_sint_ub64 (ty_bits dst_ty)))) 4941(rule (fcvt_to_sint_ub $F128 dst_ty) 4942 (vec_imm $F128 (fcvt_to_sint_ub128 (ty_bits dst_ty)))) 4943 4944(decl fcvt_to_sint_lb (Type Type) Reg) 4945(rule (fcvt_to_sint_lb $F32 dst_ty) 4946 (imm $F32 (fcvt_to_sint_lb32 (ty_bits dst_ty)))) 4947(rule (fcvt_to_sint_lb $F64 dst_ty) 4948 (imm $F64 (fcvt_to_sint_lb64 (ty_bits dst_ty)))) 4949(rule (fcvt_to_sint_lb $F128 dst_ty) 4950 (vec_imm $F128 (fcvt_to_sint_lb128 (ty_bits dst_ty)))) 4951 4952(decl fcvt_to_sint_ub32 (u8) u64) 4953(extern constructor fcvt_to_sint_ub32 fcvt_to_sint_ub32) 4954(decl fcvt_to_sint_lb32 (u8) u64) 4955(extern constructor fcvt_to_sint_lb32 fcvt_to_sint_lb32) 4956(decl fcvt_to_sint_ub64 (u8) u64) 4957(extern constructor fcvt_to_sint_ub64 fcvt_to_sint_ub64) 4958(decl fcvt_to_sint_lb64 (u8) u64) 4959(extern constructor fcvt_to_sint_lb64 fcvt_to_sint_lb64) 4960(decl fcvt_to_sint_ub128 (u8) u128) 4961(extern constructor fcvt_to_sint_ub128 fcvt_to_sint_ub128) 4962(decl fcvt_to_sint_lb128 (u8) u128) 4963(extern constructor fcvt_to_sint_lb128 fcvt_to_sint_lb128) 4964 4965 4966;; Helpers for generating signed `icmp` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;; 4967 4968(decl cmpop_cmps (Type) CmpOp) 4969(rule (cmpop_cmps $I32) (CmpOp.CmpS32)) 4970(rule (cmpop_cmps $I64) (CmpOp.CmpS64)) 4971 4972(decl cmpop_cmps_sext16 (Type) CmpOp) 4973(rule (cmpop_cmps_sext16 $I32) (CmpOp.CmpS32Ext16)) 4974(rule (cmpop_cmps_sext16 $I64) (CmpOp.CmpS64Ext16)) 4975 4976(decl cmpop_cmps_sext32 (Type) CmpOp) 4977(rule (cmpop_cmps_sext32 $I64) (CmpOp.CmpS64Ext32)) 4978 4979(decl icmps_reg (Type Reg Reg) ProducesFlags) 4980(rule (icmps_reg ty src1 src2) (cmp_rr (cmpop_cmps ty) src1 src2)) 4981 4982(decl icmps_reg_sext32 (Type Reg Reg) ProducesFlags) 4983(rule (icmps_reg_sext32 ty src1 src2) (cmp_rr (cmpop_cmps_sext32 ty) src1 src2)) 4984 4985(decl icmps_simm16 (Type Reg i16) ProducesFlags) 4986(rule (icmps_simm16 ty src imm) (cmp_rsimm16 (cmpop_cmps ty) src imm)) 4987 4988(decl icmps_simm32 (Type Reg i32) ProducesFlags) 4989(rule (icmps_simm32 ty src imm) (cmp_rsimm32 (cmpop_cmps ty) src imm)) 4990 4991(decl icmps_mem (Type Reg MemArg) ProducesFlags) 4992(rule (icmps_mem ty src mem) (cmp_rx (cmpop_cmps ty) src mem)) 4993 4994(decl icmps_mem_sext16 (Type Reg MemArg) ProducesFlags) 4995(rule (icmps_mem_sext16 ty src mem) (cmp_rx (cmpop_cmps_sext16 ty) src mem)) 4996 4997(decl icmps_mem_sext32 (Type Reg MemArg) ProducesFlags) 4998(rule (icmps_mem_sext32 ty src mem) (cmp_rx (cmpop_cmps_sext32 ty) src mem)) 4999 5000 5001;; Helpers for generating unsigned `icmp` instructions ;;;;;;;;;;;;;;;;;;;;;;;;; 5002 5003(decl cmpop_cmpu (Type) CmpOp) 5004(rule (cmpop_cmpu $I32) (CmpOp.CmpL32)) 5005(rule (cmpop_cmpu $I64) (CmpOp.CmpL64)) 5006 5007(decl cmpop_cmpu_zext16 (Type) CmpOp) 5008(rule (cmpop_cmpu_zext16 $I32) (CmpOp.CmpL32Ext16)) 5009(rule (cmpop_cmpu_zext16 $I64) (CmpOp.CmpL64Ext16)) 5010 5011(decl cmpop_cmpu_zext32 (Type) CmpOp) 5012(rule (cmpop_cmpu_zext32 $I64) (CmpOp.CmpL64Ext32)) 5013 5014(decl icmpu_reg (Type Reg Reg) ProducesFlags) 5015(rule (icmpu_reg ty src1 src2) (cmp_rr (cmpop_cmpu ty) src1 src2)) 5016 5017(decl icmpu_reg_zext32 (Type Reg Reg) ProducesFlags) 5018(rule (icmpu_reg_zext32 ty src1 src2) (cmp_rr (cmpop_cmpu_zext32 ty) src1 src2)) 5019 5020(decl icmpu_uimm32 (Type Reg u32) ProducesFlags) 5021(rule (icmpu_uimm32 ty src imm) (cmp_ruimm32 (cmpop_cmpu ty) src imm)) 5022 5023(decl icmpu_mem (Type Reg MemArg) ProducesFlags) 5024(rule (icmpu_mem ty src mem) (cmp_rx (cmpop_cmpu ty) src mem)) 5025 5026(decl icmpu_mem_zext16 (Type Reg MemArg) ProducesFlags) 5027(rule (icmpu_mem_zext16 ty src mem) (cmp_rx (cmpop_cmpu_zext16 ty) src mem)) 5028 5029(decl icmpu_mem_zext32 (Type Reg MemArg) ProducesFlags) 5030(rule (icmpu_mem_zext32 ty src mem) (cmp_rx (cmpop_cmpu_zext32 ty) src mem)) 5031 5032 5033;; Helpers for generating vector `icmp` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;; 5034 5035(decl vecop_int_cmpeq (Type) VecIntCmpOp) 5036(rule (vecop_int_cmpeq (multi_lane 8 16)) (VecIntCmpOp.CmpEq8x16)) 5037(rule (vecop_int_cmpeq (multi_lane 16 8)) (VecIntCmpOp.CmpEq16x8)) 5038(rule (vecop_int_cmpeq (multi_lane 32 4)) (VecIntCmpOp.CmpEq32x4)) 5039(rule (vecop_int_cmpeq (multi_lane 64 2)) (VecIntCmpOp.CmpEq64x2)) 5040 5041(decl vec_cmpeq (Type Reg Reg) Reg) 5042(rule (vec_cmpeq (vr128_ty ty) x y) (vec_int_cmp ty (vecop_int_cmpeq ty) x y)) 5043(decl vec_cmpeqs (Type Reg Reg) ProducesFlags) 5044(rule (vec_cmpeqs (vr128_ty ty) x y) (vec_int_cmps ty (vecop_int_cmpeq ty) x y)) 5045 5046(decl vecop_int_cmph (Type) VecIntCmpOp) 5047(rule (vecop_int_cmph (multi_lane 8 16)) (VecIntCmpOp.SCmpHi8x16)) 5048(rule (vecop_int_cmph (multi_lane 16 8)) (VecIntCmpOp.SCmpHi16x8)) 5049(rule (vecop_int_cmph (multi_lane 32 4)) (VecIntCmpOp.SCmpHi32x4)) 5050(rule (vecop_int_cmph (multi_lane 64 2)) (VecIntCmpOp.SCmpHi64x2)) 5051 5052(decl vec_cmph (Type Reg Reg) Reg) 5053(rule (vec_cmph (vr128_ty ty) x y) (vec_int_cmp ty (vecop_int_cmph ty) x y)) 5054(decl vec_cmphs (Type Reg Reg) ProducesFlags) 5055(rule (vec_cmphs (vr128_ty ty) x y) (vec_int_cmps ty (vecop_int_cmph ty) x y)) 5056 5057(decl vecop_int_cmphl (Type) VecIntCmpOp) 5058(rule (vecop_int_cmphl (multi_lane 8 16)) (VecIntCmpOp.UCmpHi8x16)) 5059(rule (vecop_int_cmphl (multi_lane 16 8)) (VecIntCmpOp.UCmpHi16x8)) 5060(rule (vecop_int_cmphl (multi_lane 32 4)) (VecIntCmpOp.UCmpHi32x4)) 5061(rule (vecop_int_cmphl (multi_lane 64 2)) (VecIntCmpOp.UCmpHi64x2)) 5062 5063(decl vec_cmphl (Type Reg Reg) Reg) 5064(rule (vec_cmphl (vr128_ty ty) x y) (vec_int_cmp ty (vecop_int_cmphl ty) x y)) 5065(decl vec_cmphls (Type Reg Reg) ProducesFlags) 5066(rule (vec_cmphls (vr128_ty ty) x y) (vec_int_cmps ty (vecop_int_cmphl ty) x y)) 5067 5068(decl vec_elt_icmps (Reg Reg) ProducesFlags) 5069(rule (vec_elt_icmps x y) (vec_int_elt_cmp (VecIntEltCmpOp.SCmp128) x y)) 5070 5071(decl vec_elt_icmpu (Reg Reg) ProducesFlags) 5072(rule (vec_elt_icmpu x y) (vec_int_elt_cmp (VecIntEltCmpOp.UCmp128) x y)) 5073 5074 5075;; Helpers for generating `fcmp` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 5076 5077(decl fcmp_reg (Type Reg Reg) ProducesFlags) 5078(rule (fcmp_reg $F32 src1 src2) (fpu_cmp32 src1 src2)) 5079(rule (fcmp_reg $F64 src1 src2) (fpu_cmp64 src1 src2)) 5080(rule (fcmp_reg $F128 src1 src2) (fpu_cmp128 src1 src2)) 5081 5082 5083;; Helpers for generating vector `fcmp` instructions ;;;;;;;;;;;;;;;;;;;;;;;;;;; 5084 5085(decl vecop_float_cmpeq (Type) VecFloatCmpOp) 5086(rule (vecop_float_cmpeq (multi_lane 32 4)) (VecFloatCmpOp.CmpEq32x4)) 5087(rule (vecop_float_cmpeq (multi_lane 64 2)) (VecFloatCmpOp.CmpEq64x2)) 5088 5089(decl vec_fcmpeq (Type Reg Reg) Reg) 5090(rule (vec_fcmpeq (ty_vec128 ty) x y) (vec_float_cmp ty (vecop_float_cmpeq ty) x y)) 5091(decl vec_fcmpeqs (Type Reg Reg) ProducesFlags) 5092(rule (vec_fcmpeqs (ty_vec128 ty) x y) (vec_float_cmps ty (vecop_float_cmpeq ty) x y)) 5093 5094(decl vecop_float_cmph (Type) VecFloatCmpOp) 5095(rule (vecop_float_cmph (multi_lane 32 4)) (VecFloatCmpOp.CmpHi32x4)) 5096(rule (vecop_float_cmph (multi_lane 64 2)) (VecFloatCmpOp.CmpHi64x2)) 5097 5098(decl vec_fcmph (Type Reg Reg) Reg) 5099(rule (vec_fcmph (ty_vec128 ty) x y) (vec_float_cmp ty (vecop_float_cmph ty) x y)) 5100(decl vec_fcmphs (Type Reg Reg) ProducesFlags) 5101(rule (vec_fcmphs (ty_vec128 ty) x y) (vec_float_cmps ty (vecop_float_cmph ty) x y)) 5102 5103(decl vecop_float_cmphe (Type) VecFloatCmpOp) 5104(rule (vecop_float_cmphe (multi_lane 32 4)) (VecFloatCmpOp.CmpHiEq32x4)) 5105(rule (vecop_float_cmphe (multi_lane 64 2)) (VecFloatCmpOp.CmpHiEq64x2)) 5106 5107(decl vec_fcmphe (Type Reg Reg) Reg) 5108(rule (vec_fcmphe (ty_vec128 ty) x y) (vec_float_cmp ty (vecop_float_cmphe ty) x y)) 5109(decl vec_fcmphes (Type Reg Reg) ProducesFlags) 5110(rule (vec_fcmphes (ty_vec128 ty) x y) (vec_float_cmps ty (vecop_float_cmphe ty) x y)) 5111 5112;; Other helpers ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 5113 5114;; Helper for creating an `LabelAddress` instruction. 5115(decl s390x_label_address (MachLabel) Reg) 5116(rule (s390x_label_address label) 5117 (let ((dst WritableReg (temp_writable_reg $I64)) 5118 (_ Unit (emit (MInst.LabelAddress dst label)))) 5119 dst)) 5120 5121;; Helper for creating a `SequencePoint` instruction. 5122(decl s390x_sequence_point () SideEffectNoResult) 5123(rule (s390x_sequence_point) 5124 (SideEffectNoResult.Inst (MInst.SequencePoint))) 5125 5126;; Implicit conversions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 5127 5128(convert WritableRegPair RegPair writable_regpair_to_regpair) 5129