395 case 0x5: 396 // SP 397 return new MsrImm64( 398 machInst, MISCREG_SPSEL, crm); 399 case 0x1e: 400 // DAIFSet 401 return new MsrImmDAIFSet64( 402 machInst, MISCREG_DAIF, crm); 403 case 0x1f: 404 // DAIFClr 405 return new MsrImmDAIFClr64( 406 machInst, MISCREG_DAIF, crm); 407 default: 408 return new Unknown64(machInst); 409 } 410 } else { 411 return new Unknown64(machInst); 412 } 413 break; 414 case 0x1: 415 case 0x2: 416 case 0x3: 417 { 418 // bit 31:22=1101010100, 20:19=11 419 bool read = l; 420 MiscRegIndex miscReg = 421 decodeAArch64SysReg(op0, op1, crn, crm, op2); 422 if (read) { 423 if ((miscReg == MISCREG_DC_CIVAC_Xt) || 424 (miscReg == MISCREG_DC_CVAC_Xt) || 425 (miscReg == MISCREG_DC_IVAC_Xt) || 426 (miscReg == MISCREG_DC_ZVA_Xt)) { 427 return new Unknown64(machInst); 428 } 429 } 430 // Check for invalid registers 431 if (miscReg == MISCREG_UNKNOWN) { 432 auto full_mnemonic = 433 csprintf("%s op0:%d op1:%d crn:%d crm:%d op2:%d", 434 read ? "mrs" : "msr", 435 op0, op1, crn, crm, op2); 436 437 return new FailUnimplemented(read ? "mrs" : "msr", 438 machInst, full_mnemonic); 439 440 } else if (miscReg == MISCREG_IMPDEF_UNIMPL) { 441 auto full_mnemonic = 442 csprintf("%s op0:%d op1:%d crn:%d crm:%d op2:%d", 443 read ? "mrs" : "msr", 444 op0, op1, crn, crm, op2); 445 446 uint32_t iss = msrMrs64IssBuild( 447 read, op0, op1, crn, crm, op2, rt); 448 449 return new MiscRegImplDefined64( 450 read ? "mrs" : "msr", 451 machInst, miscReg, read, iss, full_mnemonic, 452 miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]); 453 454 } else if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) { 455 if (miscReg == MISCREG_NZCV) { 456 if (read) 457 return new MrsNZCV64(machInst, rt, (IntRegIndex) miscReg); 458 else 459 return new MsrNZCV64(machInst, (IntRegIndex) miscReg, rt); 460 } 461 uint32_t iss = msrMrs64IssBuild(read, op0, op1, crn, crm, op2, rt); 462 if (read) { 463 StaticInstPtr si = new Mrs64(machInst, rt, miscReg, iss); 464 if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE]) 465 si->setFlag(StaticInst::IsUnverifiable); 466 return si; 467 } else { 468 switch (miscReg) { 469 case MISCREG_DC_ZVA_Xt: 470 return new Dczva(machInst, rt, miscReg, iss); 471 case MISCREG_DC_CVAU_Xt: 472 return new Dccvau(machInst, rt, miscReg, iss); 473 case MISCREG_DC_CVAC_Xt: 474 return new Dccvac(machInst, rt, miscReg, iss); 475 case MISCREG_DC_CIVAC_Xt: 476 return new Dccivac(machInst, rt, miscReg, iss); 477 case MISCREG_DC_IVAC_Xt: 478 return new Dcivac(machInst, rt, miscReg, iss); 479 default: 480 return new Msr64(machInst, miscReg, rt, iss); 481 } 482 } 483 } else if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) { 484 std::string full_mnem = csprintf("%s %s", 485 read ? "mrs" : "msr", miscRegName[miscReg]); 486 return new WarnUnimplemented(read ? "mrs" : "msr", 487 machInst, full_mnem); 488 } else { 489 return new FailUnimplemented(read ? "mrs" : "msr", 490 machInst, 491 csprintf("%s %s", 492 read ? "mrs" : "msr", 493 miscRegName[miscReg])); 494 } 495 } 496 break; 497 default: 498 M5_UNREACHABLE; 499 } 500 } else if (bits(machInst, 25) == 0x1) { 501 uint8_t opc = bits(machInst, 24, 21); 502 uint8_t op2 = bits(machInst, 20, 16); 503 uint8_t op3 = bits(machInst, 15, 10); 504 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 505 uint8_t op4 = bits(machInst, 4, 0); 506 if (op2 != 0x1f || op3 != 0x0 || op4 != 0x0) 507 return new Unknown64(machInst); 508 switch (opc) { 509 case 0x0: 510 return new Br64(machInst, rn); 511 case 0x1: 512 return new Blr64(machInst, rn); 513 case 0x2: 514 return new Ret64(machInst, rn); 515 case 0x4: 516 if (rn != 0x1f) 517 return new Unknown64(machInst); 518 return new Eret64(machInst); 519 case 0x5: 520 if (rn != 0x1f) 521 return new Unknown64(machInst); 522 return new FailUnimplemented("dret", machInst); 523 default: 524 return new Unknown64(machInst); 525 } 526 } 527 M5_FALLTHROUGH; 528 default: 529 return new Unknown64(machInst); 530 } 531 return new FailUnimplemented("Unhandled Case7", machInst); 532 } 533} 534}}; 535 536output decoder {{ 537namespace Aarch64 538{ 539 StaticInstPtr 540 decodeLoadsStores(ExtMachInst machInst) 541 { 542 // bit 27,25=10 543 switch (bits(machInst, 29, 28)) { 544 case 0x0: 545 if (bits(machInst, 26) == 0) { 546 if (bits(machInst, 24) != 0) 547 return new Unknown64(machInst); 548 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 549 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 550 IntRegIndex rnsp = makeSP(rn); 551 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 552 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 553 uint8_t opc = (bits(machInst, 15) << 0) | 554 (bits(machInst, 23, 21) << 1); 555 uint8_t size = bits(machInst, 31, 30); 556 switch (opc) { 557 case 0x0: 558 switch (size) { 559 case 0x0: 560 return new STXRB64(machInst, rt, rnsp, rs); 561 case 0x1: 562 return new STXRH64(machInst, rt, rnsp, rs); 563 case 0x2: 564 return new STXRW64(machInst, rt, rnsp, rs); 565 case 0x3: 566 return new STXRX64(machInst, rt, rnsp, rs); 567 default: 568 M5_UNREACHABLE; 569 } 570 case 0x1: 571 switch (size) { 572 case 0x0: 573 return new STLXRB64(machInst, rt, rnsp, rs); 574 case 0x1: 575 return new STLXRH64(machInst, rt, rnsp, rs); 576 case 0x2: 577 return new STLXRW64(machInst, rt, rnsp, rs); 578 case 0x3: 579 return new STLXRX64(machInst, rt, rnsp, rs); 580 default: 581 M5_UNREACHABLE; 582 } 583 case 0x2: 584 switch (size) { 585 case 0x0: 586 case 0x1: 587 return new Unknown64(machInst); 588 case 0x2: 589 return new STXPW64(machInst, rs, rt, rt2, rnsp); 590 case 0x3: 591 return new STXPX64(machInst, rs, rt, rt2, rnsp); 592 default: 593 M5_UNREACHABLE; 594 } 595 596 case 0x3: 597 switch (size) { 598 case 0x0: 599 case 0x1: 600 return new Unknown64(machInst); 601 case 0x2: 602 return new STLXPW64(machInst, rs, rt, rt2, rnsp); 603 case 0x3: 604 return new STLXPX64(machInst, rs, rt, rt2, rnsp); 605 default: 606 M5_UNREACHABLE; 607 } 608 609 case 0x4: 610 switch (size) { 611 case 0x0: 612 return new LDXRB64(machInst, rt, rnsp, rs); 613 case 0x1: 614 return new LDXRH64(machInst, rt, rnsp, rs); 615 case 0x2: 616 return new LDXRW64(machInst, rt, rnsp, rs); 617 case 0x3: 618 return new LDXRX64(machInst, rt, rnsp, rs); 619 default: 620 M5_UNREACHABLE; 621 } 622 case 0x5: 623 switch (size) { 624 case 0x0: 625 return new LDAXRB64(machInst, rt, rnsp, rs); 626 case 0x1: 627 return new LDAXRH64(machInst, rt, rnsp, rs); 628 case 0x2: 629 return new LDAXRW64(machInst, rt, rnsp, rs); 630 case 0x3: 631 return new LDAXRX64(machInst, rt, rnsp, rs); 632 default: 633 M5_UNREACHABLE; 634 } 635 case 0x6: 636 switch (size) { 637 case 0x0: 638 case 0x1: 639 return new Unknown64(machInst); 640 case 0x2: 641 return new LDXPW64(machInst, rt, rt2, rnsp); 642 case 0x3: 643 return new LDXPX64(machInst, rt, rt2, rnsp); 644 default: 645 M5_UNREACHABLE; 646 } 647 648 case 0x7: 649 switch (size) { 650 case 0x0: 651 case 0x1: 652 return new Unknown64(machInst); 653 case 0x2: 654 return new LDAXPW64(machInst, rt, rt2, rnsp); 655 case 0x3: 656 return new LDAXPX64(machInst, rt, rt2, rnsp); 657 default: 658 M5_UNREACHABLE; 659 } 660 661 case 0x9: 662 switch (size) { 663 case 0x0: 664 return new STLRB64(machInst, rt, rnsp); 665 case 0x1: 666 return new STLRH64(machInst, rt, rnsp); 667 case 0x2: 668 return new STLRW64(machInst, rt, rnsp); 669 case 0x3: 670 return new STLRX64(machInst, rt, rnsp); 671 default: 672 M5_UNREACHABLE; 673 } 674 case 0xd: 675 switch (size) { 676 case 0x0: 677 return new LDARB64(machInst, rt, rnsp); 678 case 0x1: 679 return new LDARH64(machInst, rt, rnsp); 680 case 0x2: 681 return new LDARW64(machInst, rt, rnsp); 682 case 0x3: 683 return new LDARX64(machInst, rt, rnsp); 684 default: 685 M5_UNREACHABLE; 686 } 687 default: 688 return new Unknown64(machInst); 689 } 690 } else if (bits(machInst, 31)) { 691 return new Unknown64(machInst); 692 } else { 693 return decodeNeonMem(machInst); 694 } 695 case 0x1: 696 { 697 if (bits(machInst, 24) != 0) 698 return new Unknown64(machInst); 699 uint8_t switchVal = (bits(machInst, 26) << 0) | 700 (bits(machInst, 31, 30) << 1); 701 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2; 702 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 703 switch (switchVal) { 704 case 0x0: 705 return new LDRWL64_LIT(machInst, rt, imm); 706 case 0x1: 707 return new LDRSFP64_LIT(machInst, rt, imm); 708 case 0x2: 709 return new LDRXL64_LIT(machInst, rt, imm); 710 case 0x3: 711 return new LDRDFP64_LIT(machInst, rt, imm); 712 case 0x4: 713 return new LDRSWL64_LIT(machInst, rt, imm); 714 case 0x5: 715 return new BigFpMemLit("ldr", machInst, rt, imm); 716 case 0x6: 717 return new PRFM64_LIT(machInst, rt, imm); 718 default: 719 return new Unknown64(machInst); 720 } 721 } 722 case 0x2: 723 { 724 uint8_t opc = bits(machInst, 31, 30); 725 if (opc >= 3) 726 return new Unknown64(machInst); 727 uint32_t size = 0; 728 bool fp = bits(machInst, 26); 729 bool load = bits(machInst, 22); 730 if (fp) { 731 size = 4 << opc; 732 } else { 733 if ((opc == 1) && !load) 734 return new Unknown64(machInst); 735 size = (opc == 0 || opc == 1) ? 4 : 8; 736 } 737 uint8_t type = bits(machInst, 24, 23); 738 int64_t imm = sext<7>(bits(machInst, 21, 15)) * size; 739 740 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 741 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 742 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 743 744 bool noAlloc = (type == 0); 745 bool signExt = !noAlloc && !fp && opc == 1; 746 PairMemOp::AddrMode mode; 747 const char *mnemonic = NULL; 748 switch (type) { 749 case 0x0: 750 case 0x2: 751 mode = PairMemOp::AddrMd_Offset; 752 break; 753 case 0x1: 754 mode = PairMemOp::AddrMd_PostIndex; 755 break; 756 case 0x3: 757 mode = PairMemOp::AddrMd_PreIndex; 758 break; 759 default: 760 return new Unknown64(machInst); 761 } 762 if (load) { 763 if (noAlloc) 764 mnemonic = "ldnp"; 765 else if (signExt) 766 mnemonic = "ldpsw"; 767 else 768 mnemonic = "ldp"; 769 } else { 770 if (noAlloc) 771 mnemonic = "stnp"; 772 else 773 mnemonic = "stp"; 774 } 775 776 return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc, 777 signExt, false, false, imm, mode, rn, rt, rt2); 778 } 779 // bit 29:27=111, 25=0 780 case 0x3: 781 { 782 uint8_t switchVal = (bits(machInst, 23, 22) << 0) | 783 (bits(machInst, 26) << 2) | 784 (bits(machInst, 31, 30) << 3); 785 if (bits(machInst, 24) == 1) { 786 uint64_t imm12 = bits(machInst, 21, 10); 787 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 788 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 789 IntRegIndex rnsp = makeSP(rn); 790 switch (switchVal) { 791 case 0x00: 792 return new STRB64_IMM(machInst, rt, rnsp, imm12); 793 case 0x01: 794 return new LDRB64_IMM(machInst, rt, rnsp, imm12); 795 case 0x02: 796 return new LDRSBX64_IMM(machInst, rt, rnsp, imm12); 797 case 0x03: 798 return new LDRSBW64_IMM(machInst, rt, rnsp, imm12); 799 case 0x04: 800 return new STRBFP64_IMM(machInst, rt, rnsp, imm12); 801 case 0x05: 802 return new LDRBFP64_IMM(machInst, rt, rnsp, imm12); 803 case 0x06: 804 return new BigFpMemImm("str", machInst, false, 805 rt, rnsp, imm12 << 4); 806 case 0x07: 807 return new BigFpMemImm("ldr", machInst, true, 808 rt, rnsp, imm12 << 4); 809 case 0x08: 810 return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1); 811 case 0x09: 812 return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1); 813 case 0x0a: 814 return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1); 815 case 0x0b: 816 return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1); 817 case 0x0c: 818 return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 819 case 0x0d: 820 return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 821 case 0x10: 822 return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2); 823 case 0x11: 824 return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2); 825 case 0x12: 826 return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2); 827 case 0x14: 828 return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 829 case 0x15: 830 return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 831 case 0x18: 832 return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3); 833 case 0x19: 834 return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3); 835 case 0x1a: 836 return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3); 837 case 0x1c: 838 return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 839 case 0x1d: 840 return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 841 default: 842 return new Unknown64(machInst); 843 } 844 } else if (bits(machInst, 21) == 1) { 845 uint8_t group = bits(machInst, 11, 10); 846 switch (group) { 847 case 0x0: 848 { 849 if ((switchVal & 0x7) == 0x2 && 850 bits(machInst, 20, 12) == 0x1fc) { 851 IntRegIndex rt = (IntRegIndex)(uint32_t) 852 bits(machInst, 4, 0); 853 IntRegIndex rn = (IntRegIndex)(uint32_t) 854 bits(machInst, 9, 5); 855 IntRegIndex rnsp = makeSP(rn); 856 uint8_t size = bits(machInst, 31, 30); 857 switch (size) { 858 case 0x0: 859 return new LDAPRB64(machInst, rt, rnsp); 860 case 0x1: 861 return new LDAPRH64(machInst, rt, rnsp); 862 case 0x2: 863 return new LDAPRW64(machInst, rt, rnsp); 864 case 0x3: 865 return new LDAPRX64(machInst, rt, rnsp); 866 default: 867 M5_UNREACHABLE; 868 } 869 } else { 870 return new Unknown64(machInst); 871 } 872 } 873 case 0x2: 874 { 875 if (!bits(machInst, 14)) 876 return new Unknown64(machInst); 877 IntRegIndex rt = (IntRegIndex)(uint32_t) 878 bits(machInst, 4, 0); 879 IntRegIndex rn = (IntRegIndex)(uint32_t) 880 bits(machInst, 9, 5); 881 IntRegIndex rnsp = makeSP(rn); 882 IntRegIndex rm = (IntRegIndex)(uint32_t) 883 bits(machInst, 20, 16); 884 ArmExtendType type = 885 (ArmExtendType)(uint32_t)bits(machInst, 15, 13); 886 uint8_t s = bits(machInst, 12); 887 switch (switchVal) { 888 case 0x00: 889 return new STRB64_REG(machInst, rt, rnsp, rm, 890 type, 0); 891 case 0x01: 892 return new LDRB64_REG(machInst, rt, rnsp, rm, 893 type, 0); 894 case 0x02: 895 return new LDRSBX64_REG(machInst, rt, rnsp, rm, 896 type, 0); 897 case 0x03: 898 return new LDRSBW64_REG(machInst, rt, rnsp, rm, 899 type, 0); 900 case 0x04: 901 return new STRBFP64_REG(machInst, rt, rnsp, rm, 902 type, 0); 903 case 0x05: 904 return new LDRBFP64_REG(machInst, rt, rnsp, rm, 905 type, 0); 906 case 0x6: 907 return new BigFpMemReg("str", machInst, false, 908 rt, rnsp, rm, type, s * 4); 909 case 0x7: 910 return new BigFpMemReg("ldr", machInst, true, 911 rt, rnsp, rm, type, s * 4); 912 case 0x08: 913 return new STRH64_REG(machInst, rt, rnsp, rm, 914 type, s); 915 case 0x09: 916 return new LDRH64_REG(machInst, rt, rnsp, rm, 917 type, s); 918 case 0x0a: 919 return new LDRSHX64_REG(machInst, rt, rnsp, rm, 920 type, s); 921 case 0x0b: 922 return new LDRSHW64_REG(machInst, rt, rnsp, rm, 923 type, s); 924 case 0x0c: 925 return new STRHFP64_REG(machInst, rt, rnsp, rm, 926 type, s); 927 case 0x0d: 928 return new LDRHFP64_REG(machInst, rt, rnsp, rm, 929 type, s); 930 case 0x10: 931 return new STRW64_REG(machInst, rt, rnsp, rm, 932 type, s * 2); 933 case 0x11: 934 return new LDRW64_REG(machInst, rt, rnsp, rm, 935 type, s * 2); 936 case 0x12: 937 return new LDRSW64_REG(machInst, rt, rnsp, rm, 938 type, s * 2); 939 case 0x14: 940 return new STRSFP64_REG(machInst, rt, rnsp, rm, 941 type, s * 2); 942 case 0x15: 943 return new LDRSFP64_REG(machInst, rt, rnsp, rm, 944 type, s * 2); 945 case 0x18: 946 return new STRX64_REG(machInst, rt, rnsp, rm, 947 type, s * 3); 948 case 0x19: 949 return new LDRX64_REG(machInst, rt, rnsp, rm, 950 type, s * 3); 951 case 0x1a: 952 return new PRFM64_REG(machInst, rt, rnsp, rm, 953 type, s * 3); 954 case 0x1c: 955 return new STRDFP64_REG(machInst, rt, rnsp, rm, 956 type, s * 3); 957 case 0x1d: 958 return new LDRDFP64_REG(machInst, rt, rnsp, rm, 959 type, s * 3); 960 default: 961 return new Unknown64(machInst); 962 963 } 964 } 965 default: 966 return new Unknown64(machInst); 967 } 968 } else { 969 // bit 29:27=111, 25:24=00, 21=0 970 switch (bits(machInst, 11, 10)) { 971 case 0x0: 972 { 973 IntRegIndex rt = 974 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 975 IntRegIndex rn = 976 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 977 IntRegIndex rnsp = makeSP(rn); 978 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 979 switch (switchVal) { 980 case 0x00: 981 return new STURB64_IMM(machInst, rt, rnsp, imm); 982 case 0x01: 983 return new LDURB64_IMM(machInst, rt, rnsp, imm); 984 case 0x02: 985 return new LDURSBX64_IMM(machInst, rt, rnsp, imm); 986 case 0x03: 987 return new LDURSBW64_IMM(machInst, rt, rnsp, imm); 988 case 0x04: 989 return new STURBFP64_IMM(machInst, rt, rnsp, imm); 990 case 0x05: 991 return new LDURBFP64_IMM(machInst, rt, rnsp, imm); 992 case 0x06: 993 return new BigFpMemImm("stur", machInst, false, 994 rt, rnsp, imm); 995 case 0x07: 996 return new BigFpMemImm("ldur", machInst, true, 997 rt, rnsp, imm); 998 case 0x08: 999 return new STURH64_IMM(machInst, rt, rnsp, imm); 1000 case 0x09: 1001 return new LDURH64_IMM(machInst, rt, rnsp, imm); 1002 case 0x0a: 1003 return new LDURSHX64_IMM(machInst, rt, rnsp, imm); 1004 case 0x0b: 1005 return new LDURSHW64_IMM(machInst, rt, rnsp, imm); 1006 case 0x0c: 1007 return new STURHFP64_IMM(machInst, rt, rnsp, imm); 1008 case 0x0d: 1009 return new LDURHFP64_IMM(machInst, rt, rnsp, imm); 1010 case 0x10: 1011 return new STURW64_IMM(machInst, rt, rnsp, imm); 1012 case 0x11: 1013 return new LDURW64_IMM(machInst, rt, rnsp, imm); 1014 case 0x12: 1015 return new LDURSW64_IMM(machInst, rt, rnsp, imm); 1016 case 0x14: 1017 return new STURSFP64_IMM(machInst, rt, rnsp, imm); 1018 case 0x15: 1019 return new LDURSFP64_IMM(machInst, rt, rnsp, imm); 1020 case 0x18: 1021 return new STURX64_IMM(machInst, rt, rnsp, imm); 1022 case 0x19: 1023 return new LDURX64_IMM(machInst, rt, rnsp, imm); 1024 case 0x1a: 1025 return new PRFUM64_IMM(machInst, rt, rnsp, imm); 1026 case 0x1c: 1027 return new STURDFP64_IMM(machInst, rt, rnsp, imm); 1028 case 0x1d: 1029 return new LDURDFP64_IMM(machInst, rt, rnsp, imm); 1030 default: 1031 return new Unknown64(machInst); 1032 } 1033 } 1034 // bit 29:27=111, 25:24=00, 21=0, 11:10=01 1035 case 0x1: 1036 { 1037 IntRegIndex rt = 1038 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1039 IntRegIndex rn = 1040 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1041 IntRegIndex rnsp = makeSP(rn); 1042 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1043 switch (switchVal) { 1044 case 0x00: 1045 return new STRB64_POST(machInst, rt, rnsp, imm); 1046 case 0x01: 1047 return new LDRB64_POST(machInst, rt, rnsp, imm); 1048 case 0x02: 1049 return new LDRSBX64_POST(machInst, rt, rnsp, imm); 1050 case 0x03: 1051 return new LDRSBW64_POST(machInst, rt, rnsp, imm); 1052 case 0x04: 1053 return new STRBFP64_POST(machInst, rt, rnsp, imm); 1054 case 0x05: 1055 return new LDRBFP64_POST(machInst, rt, rnsp, imm); 1056 case 0x06: 1057 return new BigFpMemPost("str", machInst, false, 1058 rt, rnsp, imm); 1059 case 0x07: 1060 return new BigFpMemPost("ldr", machInst, true, 1061 rt, rnsp, imm); 1062 case 0x08: 1063 return new STRH64_POST(machInst, rt, rnsp, imm); 1064 case 0x09: 1065 return new LDRH64_POST(machInst, rt, rnsp, imm); 1066 case 0x0a: 1067 return new LDRSHX64_POST(machInst, rt, rnsp, imm); 1068 case 0x0b: 1069 return new LDRSHW64_POST(machInst, rt, rnsp, imm); 1070 case 0x0c: 1071 return new STRHFP64_POST(machInst, rt, rnsp, imm); 1072 case 0x0d: 1073 return new LDRHFP64_POST(machInst, rt, rnsp, imm); 1074 case 0x10: 1075 return new STRW64_POST(machInst, rt, rnsp, imm); 1076 case 0x11: 1077 return new LDRW64_POST(machInst, rt, rnsp, imm); 1078 case 0x12: 1079 return new LDRSW64_POST(machInst, rt, rnsp, imm); 1080 case 0x14: 1081 return new STRSFP64_POST(machInst, rt, rnsp, imm); 1082 case 0x15: 1083 return new LDRSFP64_POST(machInst, rt, rnsp, imm); 1084 case 0x18: 1085 return new STRX64_POST(machInst, rt, rnsp, imm); 1086 case 0x19: 1087 return new LDRX64_POST(machInst, rt, rnsp, imm); 1088 case 0x1c: 1089 return new STRDFP64_POST(machInst, rt, rnsp, imm); 1090 case 0x1d: 1091 return new LDRDFP64_POST(machInst, rt, rnsp, imm); 1092 default: 1093 return new Unknown64(machInst); 1094 } 1095 } 1096 case 0x2: 1097 { 1098 IntRegIndex rt = 1099 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1100 IntRegIndex rn = 1101 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1102 IntRegIndex rnsp = makeSP(rn); 1103 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1104 switch (switchVal) { 1105 case 0x00: 1106 return new STTRB64_IMM(machInst, rt, rnsp, imm); 1107 case 0x01: 1108 return new LDTRB64_IMM(machInst, rt, rnsp, imm); 1109 case 0x02: 1110 return new LDTRSBX64_IMM(machInst, rt, rnsp, imm); 1111 case 0x03: 1112 return new LDTRSBW64_IMM(machInst, rt, rnsp, imm); 1113 case 0x08: 1114 return new STTRH64_IMM(machInst, rt, rnsp, imm); 1115 case 0x09: 1116 return new LDTRH64_IMM(machInst, rt, rnsp, imm); 1117 case 0x0a: 1118 return new LDTRSHX64_IMM(machInst, rt, rnsp, imm); 1119 case 0x0b: 1120 return new LDTRSHW64_IMM(machInst, rt, rnsp, imm); 1121 case 0x10: 1122 return new STTRW64_IMM(machInst, rt, rnsp, imm); 1123 case 0x11: 1124 return new LDTRW64_IMM(machInst, rt, rnsp, imm); 1125 case 0x12: 1126 return new LDTRSW64_IMM(machInst, rt, rnsp, imm); 1127 case 0x18: 1128 return new STTRX64_IMM(machInst, rt, rnsp, imm); 1129 case 0x19: 1130 return new LDTRX64_IMM(machInst, rt, rnsp, imm); 1131 default: 1132 return new Unknown64(machInst); 1133 } 1134 } 1135 case 0x3: 1136 { 1137 IntRegIndex rt = 1138 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1139 IntRegIndex rn = 1140 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1141 IntRegIndex rnsp = makeSP(rn); 1142 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1143 switch (switchVal) { 1144 case 0x00: 1145 return new STRB64_PRE(machInst, rt, rnsp, imm); 1146 case 0x01: 1147 return new LDRB64_PRE(machInst, rt, rnsp, imm); 1148 case 0x02: 1149 return new LDRSBX64_PRE(machInst, rt, rnsp, imm); 1150 case 0x03: 1151 return new LDRSBW64_PRE(machInst, rt, rnsp, imm); 1152 case 0x04: 1153 return new STRBFP64_PRE(machInst, rt, rnsp, imm); 1154 case 0x05: 1155 return new LDRBFP64_PRE(machInst, rt, rnsp, imm); 1156 case 0x06: 1157 return new BigFpMemPre("str", machInst, false, 1158 rt, rnsp, imm); 1159 case 0x07: 1160 return new BigFpMemPre("ldr", machInst, true, 1161 rt, rnsp, imm); 1162 case 0x08: 1163 return new STRH64_PRE(machInst, rt, rnsp, imm); 1164 case 0x09: 1165 return new LDRH64_PRE(machInst, rt, rnsp, imm); 1166 case 0x0a: 1167 return new LDRSHX64_PRE(machInst, rt, rnsp, imm); 1168 case 0x0b: 1169 return new LDRSHW64_PRE(machInst, rt, rnsp, imm); 1170 case 0x0c: 1171 return new STRHFP64_PRE(machInst, rt, rnsp, imm); 1172 case 0x0d: 1173 return new LDRHFP64_PRE(machInst, rt, rnsp, imm); 1174 case 0x10: 1175 return new STRW64_PRE(machInst, rt, rnsp, imm); 1176 case 0x11: 1177 return new LDRW64_PRE(machInst, rt, rnsp, imm); 1178 case 0x12: 1179 return new LDRSW64_PRE(machInst, rt, rnsp, imm); 1180 case 0x14: 1181 return new STRSFP64_PRE(machInst, rt, rnsp, imm); 1182 case 0x15: 1183 return new LDRSFP64_PRE(machInst, rt, rnsp, imm); 1184 case 0x18: 1185 return new STRX64_PRE(machInst, rt, rnsp, imm); 1186 case 0x19: 1187 return new LDRX64_PRE(machInst, rt, rnsp, imm); 1188 case 0x1c: 1189 return new STRDFP64_PRE(machInst, rt, rnsp, imm); 1190 case 0x1d: 1191 return new LDRDFP64_PRE(machInst, rt, rnsp, imm); 1192 default: 1193 return new Unknown64(machInst); 1194 } 1195 } 1196 default: 1197 M5_UNREACHABLE; 1198 } 1199 } 1200 } 1201 default: 1202 M5_UNREACHABLE; 1203 } 1204 return new FailUnimplemented("Unhandled Case1", machInst); 1205 } 1206} 1207}}; 1208 1209output decoder {{ 1210namespace Aarch64 1211{ 1212 StaticInstPtr 1213 decodeDataProcReg(ExtMachInst machInst) 1214 { 1215 uint8_t switchVal = (bits(machInst, 28) << 1) | 1216 (bits(machInst, 24) << 0); 1217 switch (switchVal) { 1218 case 0x0: 1219 { 1220 uint8_t switchVal = (bits(machInst, 21) << 0) | 1221 (bits(machInst, 30, 29) << 1); 1222 ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1223 uint8_t imm6 = bits(machInst, 15, 10); 1224 bool sf = bits(machInst, 31); 1225 if (!sf && (imm6 & 0x20)) 1226 return new Unknown64(machInst); 1227 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1228 IntRegIndex rdzr = makeZero(rd); 1229 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1230 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1231 1232 switch (switchVal) { 1233 case 0x0: 1234 return new AndXSReg(machInst, rdzr, rn, rm, imm6, type); 1235 case 0x1: 1236 return new BicXSReg(machInst, rdzr, rn, rm, imm6, type); 1237 case 0x2: 1238 return new OrrXSReg(machInst, rdzr, rn, rm, imm6, type); 1239 case 0x3: 1240 return new OrnXSReg(machInst, rdzr, rn, rm, imm6, type); 1241 case 0x4: 1242 return new EorXSReg(machInst, rdzr, rn, rm, imm6, type); 1243 case 0x5: 1244 return new EonXSReg(machInst, rdzr, rn, rm, imm6, type); 1245 case 0x6: 1246 return new AndXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1247 case 0x7: 1248 return new BicXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1249 default: 1250 M5_UNREACHABLE; 1251 } 1252 } 1253 case 0x1: 1254 { 1255 uint8_t switchVal = bits(machInst, 30, 29); 1256 if (bits(machInst, 21) == 0) { 1257 ArmShiftType type = 1258 (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1259 if (type == ROR) 1260 return new Unknown64(machInst); 1261 uint8_t imm6 = bits(machInst, 15, 10); 1262 if (!bits(machInst, 31) && bits(imm6, 5)) 1263 return new Unknown64(machInst); 1264 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1265 IntRegIndex rdzr = makeZero(rd); 1266 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1267 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1268 switch (switchVal) { 1269 case 0x0: 1270 return new AddXSReg(machInst, rdzr, rn, rm, imm6, type); 1271 case 0x1: 1272 return new AddXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1273 case 0x2: 1274 return new SubXSReg(machInst, rdzr, rn, rm, imm6, type); 1275 case 0x3: 1276 return new SubXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1277 default: 1278 M5_UNREACHABLE; 1279 } 1280 } else { 1281 if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4) 1282 return new Unknown64(machInst); 1283 ArmExtendType type = 1284 (ArmExtendType)(uint8_t)bits(machInst, 15, 13); 1285 uint8_t imm3 = bits(machInst, 12, 10); 1286 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1287 IntRegIndex rdsp = makeSP(rd); 1288 IntRegIndex rdzr = makeZero(rd); 1289 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1290 IntRegIndex rnsp = makeSP(rn); 1291 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1292 1293 switch (switchVal) { 1294 case 0x0: 1295 return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1296 case 0x1: 1297 return new AddXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1298 case 0x2: 1299 return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1300 case 0x3: 1301 return new SubXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1302 default: 1303 M5_UNREACHABLE; 1304 } 1305 } 1306 } 1307 case 0x2: 1308 { 1309 if (bits(machInst, 21) == 1) 1310 return new Unknown64(machInst); 1311 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1312 IntRegIndex rdzr = makeZero(rd); 1313 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1314 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1315 switch (bits(machInst, 23, 22)) { 1316 case 0x0: 1317 { 1318 if (bits(machInst, 15, 10)) 1319 return new Unknown64(machInst); 1320 uint8_t switchVal = bits(machInst, 30, 29); 1321 switch (switchVal) { 1322 case 0x0: 1323 return new AdcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1324 case 0x1: 1325 return new AdcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1326 case 0x2: 1327 return new SbcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1328 case 0x3: 1329 return new SbcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1330 default: 1331 M5_UNREACHABLE; 1332 } 1333 } 1334 case 0x1: 1335 { 1336 if ((bits(machInst, 4) == 1) || 1337 (bits(machInst, 10) == 1) || 1338 (bits(machInst, 29) == 0)) { 1339 return new Unknown64(machInst); 1340 } 1341 ConditionCode cond = 1342 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1343 uint8_t flags = bits(machInst, 3, 0); 1344 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1345 if (bits(machInst, 11) == 0) { 1346 IntRegIndex rm = 1347 (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1348 if (bits(machInst, 30) == 0) { 1349 return new CcmnReg64(machInst, rn, rm, cond, flags); 1350 } else { 1351 return new CcmpReg64(machInst, rn, rm, cond, flags); 1352 } 1353 } else { 1354 uint8_t imm5 = bits(machInst, 20, 16); 1355 if (bits(machInst, 30) == 0) { 1356 return new CcmnImm64(machInst, rn, imm5, cond, flags); 1357 } else { 1358 return new CcmpImm64(machInst, rn, imm5, cond, flags); 1359 } 1360 } 1361 } 1362 case 0x2: 1363 { 1364 if (bits(machInst, 29) == 1 || 1365 bits(machInst, 11) == 1) { 1366 return new Unknown64(machInst); 1367 } 1368 uint8_t switchVal = (bits(machInst, 10) << 0) | 1369 (bits(machInst, 30) << 1); 1370 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1371 IntRegIndex rdzr = makeZero(rd); 1372 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1373 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1374 ConditionCode cond = 1375 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1376 switch (switchVal) { 1377 case 0x0: 1378 return new Csel64(machInst, rdzr, rn, rm, cond); 1379 case 0x1: 1380 return new Csinc64(machInst, rdzr, rn, rm, cond); 1381 case 0x2: 1382 return new Csinv64(machInst, rdzr, rn, rm, cond); 1383 case 0x3: 1384 return new Csneg64(machInst, rdzr, rn, rm, cond); 1385 default: 1386 M5_UNREACHABLE; 1387 } 1388 } 1389 case 0x3: 1390 if (bits(machInst, 30) == 0) { 1391 if (bits(machInst, 29) != 0) 1392 return new Unknown64(machInst); 1393 uint8_t switchVal = bits(machInst, 15, 10); 1394 switch (switchVal) { 1395 case 0x2: 1396 return new Udiv64(machInst, rdzr, rn, rm); 1397 case 0x3: 1398 return new Sdiv64(machInst, rdzr, rn, rm); 1399 case 0x8: 1400 return new Lslv64(machInst, rdzr, rn, rm); 1401 case 0x9: 1402 return new Lsrv64(machInst, rdzr, rn, rm); 1403 case 0xa: 1404 return new Asrv64(machInst, rdzr, rn, rm); 1405 case 0xb: 1406 return new Rorv64(machInst, rdzr, rn, rm); 1407 case 0x10: 1408 return new Crc32b64(machInst, rdzr, rn, rm); 1409 case 0x11: 1410 return new Crc32h64(machInst, rdzr, rn, rm); 1411 case 0x12: 1412 return new Crc32w64(machInst, rdzr, rn, rm); 1413 case 0x13: 1414 return new Crc32x64(machInst, rdzr, rn, rm); 1415 case 0x14: 1416 return new Crc32cb64(machInst, rdzr, rn, rm); 1417 case 0x15: 1418 return new Crc32ch64(machInst, rdzr, rn, rm); 1419 case 0x16: 1420 return new Crc32cw64(machInst, rdzr, rn, rm); 1421 case 0x17: 1422 return new Crc32cx64(machInst, rdzr, rn, rm); 1423 default: 1424 return new Unknown64(machInst); 1425 } 1426 } else { 1427 if (bits(machInst, 20, 16) != 0 || 1428 bits(machInst, 29) != 0) { 1429 return new Unknown64(machInst); 1430 } 1431 uint8_t switchVal = bits(machInst, 15, 10); 1432 switch (switchVal) { 1433 case 0x0: 1434 return new Rbit64(machInst, rdzr, rn); 1435 case 0x1: 1436 return new Rev1664(machInst, rdzr, rn); 1437 case 0x2: 1438 if (bits(machInst, 31) == 0) 1439 return new Rev64(machInst, rdzr, rn); 1440 else 1441 return new Rev3264(machInst, rdzr, rn); 1442 case 0x3: 1443 if (bits(machInst, 31) != 1) 1444 return new Unknown64(machInst); 1445 return new Rev64(machInst, rdzr, rn); 1446 case 0x4: 1447 return new Clz64(machInst, rdzr, rn); 1448 case 0x5: 1449 return new Cls64(machInst, rdzr, rn); 1450 default: 1451 return new Unknown64(machInst); 1452 } 1453 } 1454 default: 1455 M5_UNREACHABLE; 1456 } 1457 } 1458 case 0x3: 1459 { 1460 if (bits(machInst, 30, 29) != 0x0 || 1461 (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0)) 1462 return new Unknown64(machInst); 1463 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1464 IntRegIndex rdzr = makeZero(rd); 1465 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1466 IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 1467 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1468 switch (bits(machInst, 23, 21)) { 1469 case 0x0: 1470 if (bits(machInst, 15) == 0) 1471 return new Madd64(machInst, rdzr, ra, rn, rm); 1472 else 1473 return new Msub64(machInst, rdzr, ra, rn, rm); 1474 case 0x1: 1475 if (bits(machInst, 15) == 0) 1476 return new Smaddl64(machInst, rdzr, ra, rn, rm); 1477 else 1478 return new Smsubl64(machInst, rdzr, ra, rn, rm); 1479 case 0x2: 1480 if (bits(machInst, 15) != 0) 1481 return new Unknown64(machInst); 1482 return new Smulh64(machInst, rdzr, rn, rm); 1483 case 0x5: 1484 if (bits(machInst, 15) == 0) 1485 return new Umaddl64(machInst, rdzr, ra, rn, rm); 1486 else 1487 return new Umsubl64(machInst, rdzr, ra, rn, rm); 1488 case 0x6: 1489 if (bits(machInst, 15) != 0) 1490 return new Unknown64(machInst); 1491 return new Umulh64(machInst, rdzr, rn, rm); 1492 default: 1493 return new Unknown64(machInst); 1494 } 1495 } 1496 default: 1497 M5_UNREACHABLE; 1498 } 1499 return new FailUnimplemented("Unhandled Case2", machInst); 1500 } 1501} 1502}}; 1503 1504output decoder {{ 1505namespace Aarch64 1506{ 1507 template <typename DecoderFeatures> 1508 StaticInstPtr 1509 decodeAdvSIMD(ExtMachInst machInst) 1510 { 1511 if (bits(machInst, 24) == 1) { 1512 if (bits(machInst, 10) == 0) { 1513 return decodeNeonIndexedElem<DecoderFeatures>(machInst); 1514 } else if (bits(machInst, 23) == 1) { 1515 return new Unknown64(machInst); 1516 } else { 1517 if (bits(machInst, 22, 19)) { 1518 return decodeNeonShiftByImm(machInst); 1519 } else { 1520 return decodeNeonModImm(machInst); 1521 } 1522 } 1523 } else if (bits(machInst, 21) == 1) { 1524 if (bits(machInst, 10) == 1) { 1525 return decodeNeon3Same<DecoderFeatures>(machInst); 1526 } else if (bits(machInst, 11) == 0) { 1527 return decodeNeon3Diff(machInst); 1528 } else if (bits(machInst, 20, 17) == 0x0) { 1529 return decodeNeon2RegMisc(machInst); 1530 } else if (bits(machInst, 20, 17) == 0x4) { 1531 return decodeCryptoAES(machInst); 1532 } else if (bits(machInst, 20, 17) == 0x8) { 1533 return decodeNeonAcrossLanes(machInst); 1534 } else { 1535 return new Unknown64(machInst); 1536 } 1537 } else if (bits(machInst, 24) || 1538 bits(machInst, 21) || 1539 bits(machInst, 15)) { 1540 return new Unknown64(machInst); 1541 } else if (bits(machInst, 10) == 1) { 1542 if (bits(machInst, 23, 22)) 1543 return new Unknown64(machInst); 1544 return decodeNeonCopy(machInst); 1545 } else if (bits(machInst, 29) == 1) { 1546 return decodeNeonExt(machInst); 1547 } else if (bits(machInst, 11) == 1) { 1548 return decodeNeonZipUzpTrn(machInst); 1549 } else if (bits(machInst, 23, 22) == 0x0) { 1550 return decodeNeonTblTbx(machInst); 1551 } else { 1552 return new Unknown64(machInst); 1553 } 1554 return new FailUnimplemented("Unhandled Case3", machInst); 1555 } 1556} 1557}}; 1558 1559 1560output decoder {{ 1561namespace Aarch64 1562{ 1563 StaticInstPtr 1564 // bit 30=0, 28:25=1111 1565 decodeFp(ExtMachInst machInst) 1566 { 1567 if (bits(machInst, 24) == 1) { 1568 if (bits(machInst, 31) || bits(machInst, 29)) 1569 return new Unknown64(machInst); 1570 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1571 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1572 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 1573 IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 14, 10); 1574 uint8_t switchVal = (bits(machInst, 23, 21) << 1) | 1575 (bits(machInst, 15) << 0); 1576 switch (switchVal) { 1577 case 0x0: // FMADD Sd = Sa + Sn*Sm 1578 return new FMAddS(machInst, rd, rn, rm, ra); 1579 case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm 1580 return new FMSubS(machInst, rd, rn, rm, ra); 1581 case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm 1582 return new FNMAddS(machInst, rd, rn, rm, ra); 1583 case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm 1584 return new FNMSubS(machInst, rd, rn, rm, ra); 1585 case 0x4: // FMADD Dd = Da + Dn*Dm 1586 return new FMAddD(machInst, rd, rn, rm, ra); 1587 case 0x5: // FMSUB Dd = Da + (-Dn)*Dm 1588 return new FMSubD(machInst, rd, rn, rm, ra); 1589 case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm 1590 return new FNMAddD(machInst, rd, rn, rm, ra); 1591 case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm 1592 return new FNMSubD(machInst, rd, rn, rm, ra); 1593 default: 1594 return new Unknown64(machInst); 1595 } 1596 } else if (bits(machInst, 21) == 0) { 1597 bool s = bits(machInst, 29); 1598 if (s) 1599 return new Unknown64(machInst); 1600 uint8_t switchVal = bits(machInst, 20, 16); 1601 uint8_t type = bits(machInst, 23, 22); 1602 uint8_t scale = bits(machInst, 15, 10); 1603 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1604 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1605 if (bits(machInst, 18, 17) == 3 && scale != 0) 1606 return new Unknown64(machInst); 1607 // 30:24=0011110, 21=0 1608 switch (switchVal) { 1609 case 0x00: 1610 return new FailUnimplemented("fcvtns", machInst); 1611 case 0x01: 1612 return new FailUnimplemented("fcvtnu", machInst); 1613 case 0x02: 1614 switch ( (bits(machInst, 31) << 2) | type ) { 1615 case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits)) 1616 return new FcvtSFixedFpSW(machInst, rd, rn, scale); 1617 case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits)) 1618 return new FcvtSFixedFpDW(machInst, rd, rn, scale); 1619 case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits)) 1620 return new FcvtSFixedFpSX(machInst, rd, rn, scale); 1621 case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits)) 1622 return new FcvtSFixedFpDX(machInst, rd, rn, scale); 1623 default: 1624 return new Unknown64(machInst); 1625 } 1626 case 0x03: 1627 switch ( (bits(machInst, 31) << 2) | type ) { 1628 case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits)) 1629 return new FcvtUFixedFpSW(machInst, rd, rn, scale); 1630 case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits)) 1631 return new FcvtUFixedFpDW(machInst, rd, rn, scale); 1632 case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits)) 1633 return new FcvtUFixedFpSX(machInst, rd, rn, scale); 1634 case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits)) 1635 return new FcvtUFixedFpDX(machInst, rd, rn, scale); 1636 default: 1637 return new Unknown64(machInst); 1638 } 1639 case 0x04: 1640 return new FailUnimplemented("fcvtas", machInst); 1641 case 0x05: 1642 return new FailUnimplemented("fcvtau", machInst); 1643 case 0x08: 1644 return new FailUnimplemented("fcvtps", machInst); 1645 case 0x09: 1646 return new FailUnimplemented("fcvtpu", machInst); 1647 case 0x0e: 1648 return new FailUnimplemented("fmov elem. to 64", machInst); 1649 case 0x0f: 1650 return new FailUnimplemented("fmov 64 bit", machInst); 1651 case 0x10: 1652 return new FailUnimplemented("fcvtms", machInst); 1653 case 0x11: 1654 return new FailUnimplemented("fcvtmu", machInst); 1655 case 0x18: 1656 switch ( (bits(machInst, 31) << 2) | type ) { 1657 case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 1658 return new FcvtFpSFixedSW(machInst, rd, rn, scale); 1659 case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 1660 return new FcvtFpSFixedDW(machInst, rd, rn, scale); 1661 case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 1662 return new FcvtFpSFixedSX(machInst, rd, rn, scale); 1663 case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 1664 return new FcvtFpSFixedDX(machInst, rd, rn, scale); 1665 default: 1666 return new Unknown64(machInst); 1667 } 1668 case 0x19: 1669 switch ( (bits(machInst, 31) << 2) | type ) { 1670 case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 1671 return new FcvtFpUFixedSW(machInst, rd, rn, scale); 1672 case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 1673 return new FcvtFpUFixedDW(machInst, rd, rn, scale); 1674 case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 1675 return new FcvtFpUFixedSX(machInst, rd, rn, scale); 1676 case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 1677 return new FcvtFpUFixedDX(machInst, rd, rn, scale); 1678 default: 1679 return new Unknown64(machInst); 1680 } 1681 default: 1682 return new Unknown64(machInst); 1683 } 1684 } else { 1685 // 30=0, 28:24=11110, 21=1 1686 uint8_t type = bits(machInst, 23, 22); 1687 uint8_t imm8 = bits(machInst, 20, 13); 1688 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1689 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1690 switch (bits(machInst, 11, 10)) { 1691 case 0x0: 1692 if (bits(machInst, 12) == 1) { 1693 if (bits(machInst, 31) || 1694 bits(machInst, 29) || 1695 bits(machInst, 9, 5)) { 1696 return new Unknown64(machInst); 1697 } 1698 // 31:29=000, 28:24=11110, 21=1, 12:10=100 1699 if (type == 0) { 1700 // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5) 1701 // :imm8<5:0>:Zeros(19) 1702 uint32_t imm = vfp_modified_imm(imm8, 1703 FpDataType::Fp32); 1704 return new FmovImmS(machInst, rd, imm); 1705 } else if (type == 1) { 1706 // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8) 1707 // :imm8<5:0>:Zeros(48) 1708 uint64_t imm = vfp_modified_imm(imm8, 1709 FpDataType::Fp64); 1710 return new FmovImmD(machInst, rd, imm); 1711 } else { 1712 return new Unknown64(machInst); 1713 } 1714 } else if (bits(machInst, 13) == 1) { 1715 if (bits(machInst, 31) || 1716 bits(machInst, 29) || 1717 bits(machInst, 15, 14) || 1718 bits(machInst, 23) || 1719 bits(machInst, 2, 0)) { 1720 return new Unknown64(machInst); 1721 } 1722 uint8_t switchVal = (bits(machInst, 4, 3) << 0) | 1723 (bits(machInst, 22) << 2); 1724 IntRegIndex rm = (IntRegIndex)(uint32_t) 1725 bits(machInst, 20, 16); 1726 // 28:23=000111100, 21=1, 15:10=001000, 2:0=000 1727 switch (switchVal) { 1728 case 0x0: 1729 // FCMP flags = compareQuiet(Sn,Sm) 1730 return new FCmpRegS(machInst, rn, rm); 1731 case 0x1: 1732 // FCMP flags = compareQuiet(Sn,0.0) 1733 return new FCmpImmS(machInst, rn, 0); 1734 case 0x2: 1735 // FCMPE flags = compareSignaling(Sn,Sm) 1736 return new FCmpERegS(machInst, rn, rm); 1737 case 0x3: 1738 // FCMPE flags = compareSignaling(Sn,0.0) 1739 return new FCmpEImmS(machInst, rn, 0); 1740 case 0x4: 1741 // FCMP flags = compareQuiet(Dn,Dm) 1742 return new FCmpRegD(machInst, rn, rm); 1743 case 0x5: 1744 // FCMP flags = compareQuiet(Dn,0.0) 1745 return new FCmpImmD(machInst, rn, 0); 1746 case 0x6: 1747 // FCMPE flags = compareSignaling(Dn,Dm) 1748 return new FCmpERegD(machInst, rn, rm); 1749 case 0x7: 1750 // FCMPE flags = compareSignaling(Dn,0.0) 1751 return new FCmpEImmD(machInst, rn, 0); 1752 default: 1753 return new Unknown64(machInst); 1754 } 1755 } else if (bits(machInst, 14) == 1) { 1756 if (bits(machInst, 31) || bits(machInst, 29)) 1757 return new Unknown64(machInst); 1758 uint8_t opcode = bits(machInst, 20, 15); 1759 // Bits 31:24=00011110, 21=1, 14:10=10000 1760 switch (opcode) { 1761 case 0x0: 1762 if (type == 0) 1763 // FMOV Sd = Sn 1764 return new FmovRegS(machInst, rd, rn); 1765 else if (type == 1) 1766 // FMOV Dd = Dn 1767 return new FmovRegD(machInst, rd, rn); 1768 break; 1769 case 0x1: 1770 if (type == 0) 1771 // FABS Sd = abs(Sn) 1772 return new FAbsS(machInst, rd, rn); 1773 else if (type == 1) 1774 // FABS Dd = abs(Dn) 1775 return new FAbsD(machInst, rd, rn); 1776 break; 1777 case 0x2: 1778 if (type == 0) 1779 // FNEG Sd = -Sn 1780 return new FNegS(machInst, rd, rn); 1781 else if (type == 1) 1782 // FNEG Dd = -Dn 1783 return new FNegD(machInst, rd, rn); 1784 break; 1785 case 0x3: 1786 if (type == 0) 1787 // FSQRT Sd = sqrt(Sn) 1788 return new FSqrtS(machInst, rd, rn); 1789 else if (type == 1) 1790 // FSQRT Dd = sqrt(Dn) 1791 return new FSqrtD(machInst, rd, rn); 1792 break; 1793 case 0x4: 1794 if (type == 1) 1795 // FCVT Sd = convertFormat(Dn) 1796 return new FcvtFpDFpS(machInst, rd, rn); 1797 else if (type == 3) 1798 // FCVT Sd = convertFormat(Hn) 1799 return new FcvtFpHFpS(machInst, rd, rn); 1800 break; 1801 case 0x5: 1802 if (type == 0) 1803 // FCVT Dd = convertFormat(Sn) 1804 return new FCvtFpSFpD(machInst, rd, rn); 1805 else if (type == 3) 1806 // FCVT Dd = convertFormat(Hn) 1807 return new FcvtFpHFpD(machInst, rd, rn); 1808 break; 1809 case 0x7: 1810 if (type == 0) 1811 // FCVT Hd = convertFormat(Sn) 1812 return new FcvtFpSFpH(machInst, rd, rn); 1813 else if (type == 1) 1814 // FCVT Hd = convertFormat(Dn) 1815 return new FcvtFpDFpH(machInst, rd, rn); 1816 break; 1817 case 0x8: 1818 if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn) 1819 return new FRIntNS(machInst, rd, rn); 1820 else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn) 1821 return new FRIntND(machInst, rd, rn); 1822 break; 1823 case 0x9: 1824 if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn) 1825 return new FRIntPS(machInst, rd, rn); 1826 else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn) 1827 return new FRIntPD(machInst, rd, rn); 1828 break; 1829 case 0xa: 1830 if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn) 1831 return new FRIntMS(machInst, rd, rn); 1832 else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn) 1833 return new FRIntMD(machInst, rd, rn); 1834 break; 1835 case 0xb: 1836 if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn) 1837 return new FRIntZS(machInst, rd, rn); 1838 else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn) 1839 return new FRIntZD(machInst, rd, rn); 1840 break; 1841 case 0xc: 1842 if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn) 1843 return new FRIntAS(machInst, rd, rn); 1844 else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn) 1845 return new FRIntAD(machInst, rd, rn); 1846 break; 1847 case 0xe: 1848 if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn) 1849 return new FRIntXS(machInst, rd, rn); 1850 else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn) 1851 return new FRIntXD(machInst, rd, rn); 1852 break; 1853 case 0xf: 1854 if (type == 0) // FRINTI Sd = roundToIntegral(Sn) 1855 return new FRIntIS(machInst, rd, rn); 1856 else if (type == 1) // FRINTI Dd = roundToIntegral(Dn) 1857 return new FRIntID(machInst, rd, rn); 1858 break; 1859 default: 1860 return new Unknown64(machInst); 1861 } 1862 return new Unknown64(machInst); 1863 } else if (bits(machInst, 15) == 1) { 1864 return new Unknown64(machInst); 1865 } else { 1866 if (bits(machInst, 29)) 1867 return new Unknown64(machInst); 1868 uint8_t rmode = bits(machInst, 20, 19); 1869 uint8_t switchVal1 = bits(machInst, 18, 16); 1870 uint8_t switchVal2 = (type << 1) | bits(machInst, 31); 1871 // 30:24=0011110, 21=1, 15:10=000000 1872 switch (switchVal1) { 1873 case 0x0: 1874 switch ((switchVal2 << 2) | rmode) { 1875 case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn) 1876 return new FcvtFpSIntWSN(machInst, rd, rn); 1877 case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn) 1878 return new FcvtFpSIntWSP(machInst, rd, rn); 1879 case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn) 1880 return new FcvtFpSIntWSM(machInst, rd, rn); 1881 case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn) 1882 return new FcvtFpSIntWSZ(machInst, rd, rn); 1883 case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn) 1884 return new FcvtFpSIntXSN(machInst, rd, rn); 1885 case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn) 1886 return new FcvtFpSIntXSP(machInst, rd, rn); 1887 case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn) 1888 return new FcvtFpSIntXSM(machInst, rd, rn); 1889 case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn) 1890 return new FcvtFpSIntXSZ(machInst, rd, rn); 1891 case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn) 1892 return new FcvtFpSIntWDN(machInst, rd, rn); 1893 case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn) 1894 return new FcvtFpSIntWDP(machInst, rd, rn); 1895 case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn) 1896 return new FcvtFpSIntWDM(machInst, rd, rn); 1897 case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn) 1898 return new FcvtFpSIntWDZ(machInst, rd, rn); 1899 case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn) 1900 return new FcvtFpSIntXDN(machInst, rd, rn); 1901 case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn) 1902 return new FcvtFpSIntXDP(machInst, rd, rn); 1903 case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn) 1904 return new FcvtFpSIntXDM(machInst, rd, rn); 1905 case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn) 1906 return new FcvtFpSIntXDZ(machInst, rd, rn); 1907 default: 1908 return new Unknown64(machInst); 1909 } 1910 case 0x1: 1911 switch ((switchVal2 << 2) | rmode) { 1912 case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn) 1913 return new FcvtFpUIntWSN(machInst, rd, rn); 1914 case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn) 1915 return new FcvtFpUIntWSP(machInst, rd, rn); 1916 case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn) 1917 return new FcvtFpUIntWSM(machInst, rd, rn); 1918 case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn) 1919 return new FcvtFpUIntWSZ(machInst, rd, rn); 1920 case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn) 1921 return new FcvtFpUIntXSN(machInst, rd, rn); 1922 case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn) 1923 return new FcvtFpUIntXSP(machInst, rd, rn); 1924 case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn) 1925 return new FcvtFpUIntXSM(machInst, rd, rn); 1926 case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn) 1927 return new FcvtFpUIntXSZ(machInst, rd, rn); 1928 case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn) 1929 return new FcvtFpUIntWDN(machInst, rd, rn); 1930 case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn) 1931 return new FcvtFpUIntWDP(machInst, rd, rn); 1932 case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn) 1933 return new FcvtFpUIntWDM(machInst, rd, rn); 1934 case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn) 1935 return new FcvtFpUIntWDZ(machInst, rd, rn); 1936 case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn) 1937 return new FcvtFpUIntXDN(machInst, rd, rn); 1938 case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn) 1939 return new FcvtFpUIntXDP(machInst, rd, rn); 1940 case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn) 1941 return new FcvtFpUIntXDM(machInst, rd, rn); 1942 case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn) 1943 return new FcvtFpUIntXDZ(machInst, rd, rn); 1944 default: 1945 return new Unknown64(machInst); 1946 } 1947 case 0x2: 1948 if (rmode != 0) 1949 return new Unknown64(machInst); 1950 switch (switchVal2) { 1951 case 0: // SCVTF Sd = convertFromInt(Wn) 1952 return new FcvtWSIntFpS(machInst, rd, rn); 1953 case 1: // SCVTF Sd = convertFromInt(Xn) 1954 return new FcvtXSIntFpS(machInst, rd, rn); 1955 case 2: // SCVTF Dd = convertFromInt(Wn) 1956 return new FcvtWSIntFpD(machInst, rd, rn); 1957 case 3: // SCVTF Dd = convertFromInt(Xn) 1958 return new FcvtXSIntFpD(machInst, rd, rn); 1959 default: 1960 return new Unknown64(machInst); 1961 } 1962 case 0x3: 1963 switch (switchVal2) { 1964 case 0: // UCVTF Sd = convertFromInt(Wn) 1965 return new FcvtWUIntFpS(machInst, rd, rn); 1966 case 1: // UCVTF Sd = convertFromInt(Xn) 1967 return new FcvtXUIntFpS(machInst, rd, rn); 1968 case 2: // UCVTF Dd = convertFromInt(Wn) 1969 return new FcvtWUIntFpD(machInst, rd, rn); 1970 case 3: // UCVTF Dd = convertFromInt(Xn) 1971 return new FcvtXUIntFpD(machInst, rd, rn); 1972 default: 1973 return new Unknown64(machInst); 1974 } 1975 case 0x4: 1976 if (rmode != 0) 1977 return new Unknown64(machInst); 1978 switch (switchVal2) { 1979 case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn) 1980 return new FcvtFpSIntWSA(machInst, rd, rn); 1981 case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn) 1982 return new FcvtFpSIntXSA(machInst, rd, rn); 1983 case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 1984 return new FcvtFpSIntWDA(machInst, rd, rn); 1985 case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 1986 return new FcvtFpSIntXDA(machInst, rd, rn); 1987 default: 1988 return new Unknown64(machInst); 1989 } 1990 case 0x5: 1991 switch (switchVal2) { 1992 case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn) 1993 return new FcvtFpUIntWSA(machInst, rd, rn); 1994 case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn) 1995 return new FcvtFpUIntXSA(machInst, rd, rn); 1996 case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn) 1997 return new FcvtFpUIntWDA(machInst, rd, rn); 1998 case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn) 1999 return new FcvtFpUIntXDA(machInst, rd, rn); 2000 default: 2001 return new Unknown64(machInst); 2002 } 2003 case 0x06: 2004 switch (switchVal2) { 2005 case 0: // FMOV Wd = Sn 2006 if (rmode != 0) 2007 return new Unknown64(machInst); 2008 return new FmovRegCoreW(machInst, rd, rn); 2009 case 3: // FMOV Xd = Dn 2010 if (rmode != 0) 2011 return new Unknown64(machInst); 2012 return new FmovRegCoreX(machInst, rd, rn); 2013 case 5: // FMOV Xd = Vn<127:64> 2014 if (rmode != 1) 2015 return new Unknown64(machInst); 2016 return new FmovURegCoreX(machInst, rd, rn); 2017 default: 2018 return new Unknown64(machInst); 2019 } 2020 break; 2021 case 0x07: 2022 switch (switchVal2) { 2023 case 0: // FMOV Sd = Wn 2024 if (rmode != 0) 2025 return new Unknown64(machInst); 2026 return new FmovCoreRegW(machInst, rd, rn); 2027 case 3: // FMOV Xd = Dn 2028 if (rmode != 0) 2029 return new Unknown64(machInst); 2030 return new FmovCoreRegX(machInst, rd, rn); 2031 case 5: // FMOV Xd = Vn<127:64> 2032 if (rmode != 1) 2033 return new Unknown64(machInst); 2034 return new FmovUCoreRegX(machInst, rd, rn); 2035 default: 2036 return new Unknown64(machInst); 2037 } 2038 break; 2039 default: // Warning! missing cases in switch statement above, that still need to be added 2040 return new Unknown64(machInst); 2041 } 2042 } 2043 M5_UNREACHABLE; 2044 case 0x1: 2045 { 2046 if (bits(machInst, 31) || 2047 bits(machInst, 29) || 2048 bits(machInst, 23)) { 2049 return new Unknown64(machInst); 2050 } 2051 IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16); 2052 IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5); 2053 uint8_t imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0); 2054 ConditionCode cond = 2055 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 2056 uint8_t switchVal = (bits(machInst, 4) << 0) | 2057 (bits(machInst, 22) << 1); 2058 // 31:23=000111100, 21=1, 11:10=01 2059 switch (switchVal) { 2060 case 0x0: 2061 // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv 2062 return new FCCmpRegS(machInst, rn, rm, cond, imm); 2063 case 0x1: 2064 // FCCMP flags = if cond then compareSignaling(Sn,Sm) 2065 // else #nzcv 2066 return new FCCmpERegS(machInst, rn, rm, cond, imm); 2067 case 0x2: 2068 // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv 2069 return new FCCmpRegD(machInst, rn, rm, cond, imm); 2070 case 0x3: 2071 // FCCMP flags = if cond then compareSignaling(Dn,Dm) 2072 // else #nzcv 2073 return new FCCmpERegD(machInst, rn, rm, cond, imm); 2074 default: 2075 return new Unknown64(machInst); 2076 } 2077 } 2078 case 0x2: 2079 { 2080 if (bits(machInst, 31) || 2081 bits(machInst, 29) || 2082 bits(machInst, 23)) { 2083 return new Unknown64(machInst); 2084 } 2085 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2086 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2087 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 2088 uint8_t switchVal = (bits(machInst, 15, 12) << 0) | 2089 (bits(machInst, 22) << 4); 2090 switch (switchVal) { 2091 case 0x00: // FMUL Sd = Sn * Sm 2092 return new FMulS(machInst, rd, rn, rm); 2093 case 0x10: // FMUL Dd = Dn * Dm 2094 return new FMulD(machInst, rd, rn, rm); 2095 case 0x01: // FDIV Sd = Sn / Sm 2096 return new FDivS(machInst, rd, rn, rm); 2097 case 0x11: // FDIV Dd = Dn / Dm 2098 return new FDivD(machInst, rd, rn, rm); 2099 case 0x02: // FADD Sd = Sn + Sm 2100 return new FAddS(machInst, rd, rn, rm); 2101 case 0x12: // FADD Dd = Dn + Dm 2102 return new FAddD(machInst, rd, rn, rm); 2103 case 0x03: // FSUB Sd = Sn - Sm 2104 return new FSubS(machInst, rd, rn, rm); 2105 case 0x13: // FSUB Dd = Dn - Dm 2106 return new FSubD(machInst, rd, rn, rm); 2107 case 0x04: // FMAX Sd = max(Sn, Sm) 2108 return new FMaxS(machInst, rd, rn, rm); 2109 case 0x14: // FMAX Dd = max(Dn, Dm) 2110 return new FMaxD(machInst, rd, rn, rm); 2111 case 0x05: // FMIN Sd = min(Sn, Sm) 2112 return new FMinS(machInst, rd, rn, rm); 2113 case 0x15: // FMIN Dd = min(Dn, Dm) 2114 return new FMinD(machInst, rd, rn, rm); 2115 case 0x06: // FMAXNM Sd = maxNum(Sn, Sm) 2116 return new FMaxNMS(machInst, rd, rn, rm); 2117 case 0x16: // FMAXNM Dd = maxNum(Dn, Dm) 2118 return new FMaxNMD(machInst, rd, rn, rm); 2119 case 0x07: // FMINNM Sd = minNum(Sn, Sm) 2120 return new FMinNMS(machInst, rd, rn, rm); 2121 case 0x17: // FMINNM Dd = minNum(Dn, Dm) 2122 return new FMinNMD(machInst, rd, rn, rm); 2123 case 0x08: // FNMUL Sd = -(Sn * Sm) 2124 return new FNMulS(machInst, rd, rn, rm); 2125 case 0x18: // FNMUL Dd = -(Dn * Dm) 2126 return new FNMulD(machInst, rd, rn, rm); 2127 default: 2128 return new Unknown64(machInst); 2129 } 2130 } 2131 case 0x3: 2132 { 2133 if (bits(machInst, 31) || bits(machInst, 29)) 2134 return new Unknown64(machInst); 2135 uint8_t type = bits(machInst, 23, 22); 2136 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2137 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2138 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 2139 ConditionCode cond = 2140 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 2141 if (type == 0) // FCSEL Sd = if cond then Sn else Sm 2142 return new FCSelS(machInst, rd, rn, rm, cond); 2143 else if (type == 1) // FCSEL Dd = if cond then Dn else Dm 2144 return new FCSelD(machInst, rd, rn, rm, cond); 2145 else 2146 return new Unknown64(machInst); 2147 } 2148 default: 2149 M5_UNREACHABLE; 2150 } 2151 } 2152 M5_UNREACHABLE; 2153 } 2154} 2155}}; 2156 2157output decoder {{ 2158namespace Aarch64 2159{ 2160 StaticInstPtr 2161 decodeAdvSIMDScalar(ExtMachInst machInst) 2162 { 2163 if (bits(machInst, 24) == 1) { 2164 if (bits(machInst, 10) == 0) { 2165 return decodeNeonScIndexedElem(machInst); 2166 } else if (bits(machInst, 23) == 0) { 2167 return decodeNeonScShiftByImm(machInst); 2168 } 2169 } else if (bits(machInst, 21) == 1) { 2170 if (bits(machInst, 10) == 1) { 2171 return decodeNeonSc3Same(machInst); 2172 } else if (bits(machInst, 11) == 0) { 2173 return decodeNeonSc3Diff(machInst); 2174 } else if (bits(machInst, 20, 17) == 0x0) { 2175 return decodeNeonSc2RegMisc(machInst); 2176 } else if (bits(machInst, 20, 17) == 0x4) { 2177 return decodeCryptoTwoRegSHA(machInst); 2178 } else if (bits(machInst, 20, 17) == 0x8) { 2179 return decodeNeonScPwise(machInst); 2180 } else { 2181 return new Unknown64(machInst); 2182 } 2183 } else if (bits(machInst, 23, 22) == 0 && 2184 bits(machInst, 15) == 0) { 2185 if (bits(machInst, 10) == 1) { 2186 return decodeNeonScCopy(machInst); 2187 } else { 2188 return decodeCryptoThreeRegSHA(machInst); 2189 } 2190 } else { 2191 return new Unknown64(machInst); 2192 } 2193 return new FailUnimplemented("Unhandled Case6", machInst); 2194 } 2195} 2196}}; 2197 2198output decoder {{ 2199namespace Aarch64 2200{ 2201 template <typename DecoderFeatures> 2202 StaticInstPtr 2203 decodeFpAdvSIMD(ExtMachInst machInst) 2204 { 2205 2206 if (bits(machInst, 28) == 0) { 2207 if (bits(machInst, 31) == 0) { 2208 return decodeAdvSIMD<DecoderFeatures>(machInst); 2209 } else { 2210 return new Unknown64(machInst); 2211 } 2212 } else if (bits(machInst, 30) == 0) { 2213 return decodeFp(machInst); 2214 } else if (bits(machInst, 31) == 0) { 2215 return decodeAdvSIMDScalar(machInst); 2216 } else { 2217 return new Unknown64(machInst); 2218 } 2219 } 2220} 2221}}; 2222 2223let {{ 2224 decoder_output =''' 2225namespace Aarch64 2226{''' 2227 for decoderFlavour, type_dict in decoders.iteritems(): 2228 decoder_output +=''' 2229template StaticInstPtr decodeFpAdvSIMD<%(df)sDecoder>(ExtMachInst machInst); 2230''' % { "df" : decoderFlavour } 2231 decoder_output +=''' 2232}''' 2233}}; 2234 2235output decoder {{ 2236namespace Aarch64 2237{ 2238 StaticInstPtr 2239 decodeGem5Ops(ExtMachInst machInst) 2240 { 2241 const uint32_t m5func = bits(machInst, 23, 16); 2242 switch (m5func) { 2243 case M5OP_ARM: return new Arm(machInst); 2244 case M5OP_QUIESCE: return new Quiesce(machInst); 2245 case M5OP_QUIESCE_NS: return new QuiesceNs64(machInst); 2246 case M5OP_QUIESCE_CYCLE: return new QuiesceCycles64(machInst); 2247 case M5OP_QUIESCE_TIME: return new QuiesceTime64(machInst); 2248 case M5OP_RPNS: return new Rpns64(machInst); 2249 case M5OP_WAKE_CPU: return new WakeCPU64(machInst); 2250 case M5OP_DEPRECATED1: return new Deprecated_ivlb(machInst); 2251 case M5OP_DEPRECATED2: return new Deprecated_ivle(machInst); 2252 case M5OP_DEPRECATED3: return new Deprecated_exit (machInst); 2253 case M5OP_EXIT: return new M5exit64(machInst); 2254 case M5OP_FAIL: return new M5fail64(machInst); 2255 case M5OP_LOAD_SYMBOL: return new Loadsymbol(machInst); 2256 case M5OP_INIT_PARAM: return new Initparam64(machInst); 2257 case M5OP_RESET_STATS: return new Resetstats64(machInst); 2258 case M5OP_DUMP_STATS: return new Dumpstats64(machInst); 2259 case M5OP_DUMP_RESET_STATS: return new Dumpresetstats64(machInst); 2260 case M5OP_CHECKPOINT: return new M5checkpoint64(machInst); 2261 case M5OP_WRITE_FILE: return new M5writefile64(machInst); 2262 case M5OP_READ_FILE: return new M5readfile64(machInst); 2263 case M5OP_DEBUG_BREAK: return new M5break(machInst); 2264 case M5OP_SWITCH_CPU: return new M5switchcpu(machInst); 2265 case M5OP_ADD_SYMBOL: return new M5addsymbol64(machInst); 2266 case M5OP_PANIC: return new M5panic(machInst); 2267 case M5OP_WORK_BEGIN: return new M5workbegin64(machInst); 2268 case M5OP_WORK_END: return new M5workend64(machInst); 2269 default: return new Unknown64(machInst); 2270 } 2271 } 2272} 2273}}; 2274 2275def format Aarch64() {{ 2276 decode_block = ''' 2277 { 2278 using namespace Aarch64; 2279 if (bits(machInst, 27) == 0x0) { 2280 if (bits(machInst, 28) == 0x0) { 2281 if (bits(machInst, 26, 25) != 0x2) { 2282 return new Unknown64(machInst); 2283 } 2284 if (bits(machInst, 31) == 0x0) { 2285 switch (bits(machInst, 30, 29)) { 2286 case 0x0: 2287 case 0x1: 2288 case 0x2: 2289 return decodeSveInt(machInst); 2290 case 0x3: 2291 return decodeSveFp(machInst); 2292 } 2293 } else { 2294 return decodeSveMem(machInst); 2295 } 2296 } else if (bits(machInst, 26) == 0) 2297 // bit 28:26=100 2298 return decodeDataProcImm(machInst); 2299 else 2300 // bit 28:26=101 2301 return decodeBranchExcSys(machInst); 2302 } else if (bits(machInst, 25) == 0) { 2303 // bit 27=1, 25=0 2304 return decodeLoadsStores(machInst); 2305 } else if (bits(machInst, 26) == 0) { 2306 // bit 27:25=101 2307 return decodeDataProcReg(machInst); 2308 } else if (bits(machInst, 24) == 1 && 2309 bits(machInst, 31, 28) == 0xF) { 2310 return decodeGem5Ops(machInst); 2311 } else { 2312 // bit 27:25=111 2313 switch(decoderFlavour){ 2314 default: 2315 return decodeFpAdvSIMD<GenericDecoder>(machInst); 2316 } 2317 } 2318 } 2319 ''' 2320}};
| 399 case 0x5: 400 // SP 401 return new MsrImm64( 402 machInst, MISCREG_SPSEL, crm); 403 case 0x1e: 404 // DAIFSet 405 return new MsrImmDAIFSet64( 406 machInst, MISCREG_DAIF, crm); 407 case 0x1f: 408 // DAIFClr 409 return new MsrImmDAIFClr64( 410 machInst, MISCREG_DAIF, crm); 411 default: 412 return new Unknown64(machInst); 413 } 414 } else { 415 return new Unknown64(machInst); 416 } 417 break; 418 case 0x1: 419 case 0x2: 420 case 0x3: 421 { 422 // bit 31:22=1101010100, 20:19=11 423 bool read = l; 424 MiscRegIndex miscReg = 425 decodeAArch64SysReg(op0, op1, crn, crm, op2); 426 if (read) { 427 if ((miscReg == MISCREG_DC_CIVAC_Xt) || 428 (miscReg == MISCREG_DC_CVAC_Xt) || 429 (miscReg == MISCREG_DC_IVAC_Xt) || 430 (miscReg == MISCREG_DC_ZVA_Xt)) { 431 return new Unknown64(machInst); 432 } 433 } 434 // Check for invalid registers 435 if (miscReg == MISCREG_UNKNOWN) { 436 auto full_mnemonic = 437 csprintf("%s op0:%d op1:%d crn:%d crm:%d op2:%d", 438 read ? "mrs" : "msr", 439 op0, op1, crn, crm, op2); 440 441 return new FailUnimplemented(read ? "mrs" : "msr", 442 machInst, full_mnemonic); 443 444 } else if (miscReg == MISCREG_IMPDEF_UNIMPL) { 445 auto full_mnemonic = 446 csprintf("%s op0:%d op1:%d crn:%d crm:%d op2:%d", 447 read ? "mrs" : "msr", 448 op0, op1, crn, crm, op2); 449 450 uint32_t iss = msrMrs64IssBuild( 451 read, op0, op1, crn, crm, op2, rt); 452 453 return new MiscRegImplDefined64( 454 read ? "mrs" : "msr", 455 machInst, miscReg, read, iss, full_mnemonic, 456 miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]); 457 458 } else if (miscRegInfo[miscReg][MISCREG_IMPLEMENTED]) { 459 if (miscReg == MISCREG_NZCV) { 460 if (read) 461 return new MrsNZCV64(machInst, rt, (IntRegIndex) miscReg); 462 else 463 return new MsrNZCV64(machInst, (IntRegIndex) miscReg, rt); 464 } 465 uint32_t iss = msrMrs64IssBuild(read, op0, op1, crn, crm, op2, rt); 466 if (read) { 467 StaticInstPtr si = new Mrs64(machInst, rt, miscReg, iss); 468 if (miscRegInfo[miscReg][MISCREG_UNVERIFIABLE]) 469 si->setFlag(StaticInst::IsUnverifiable); 470 return si; 471 } else { 472 switch (miscReg) { 473 case MISCREG_DC_ZVA_Xt: 474 return new Dczva(machInst, rt, miscReg, iss); 475 case MISCREG_DC_CVAU_Xt: 476 return new Dccvau(machInst, rt, miscReg, iss); 477 case MISCREG_DC_CVAC_Xt: 478 return new Dccvac(machInst, rt, miscReg, iss); 479 case MISCREG_DC_CIVAC_Xt: 480 return new Dccivac(machInst, rt, miscReg, iss); 481 case MISCREG_DC_IVAC_Xt: 482 return new Dcivac(machInst, rt, miscReg, iss); 483 default: 484 return new Msr64(machInst, miscReg, rt, iss); 485 } 486 } 487 } else if (miscRegInfo[miscReg][MISCREG_WARN_NOT_FAIL]) { 488 std::string full_mnem = csprintf("%s %s", 489 read ? "mrs" : "msr", miscRegName[miscReg]); 490 return new WarnUnimplemented(read ? "mrs" : "msr", 491 machInst, full_mnem); 492 } else { 493 return new FailUnimplemented(read ? "mrs" : "msr", 494 machInst, 495 csprintf("%s %s", 496 read ? "mrs" : "msr", 497 miscRegName[miscReg])); 498 } 499 } 500 break; 501 default: 502 M5_UNREACHABLE; 503 } 504 } else if (bits(machInst, 25) == 0x1) { 505 uint8_t opc = bits(machInst, 24, 21); 506 uint8_t op2 = bits(machInst, 20, 16); 507 uint8_t op3 = bits(machInst, 15, 10); 508 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 509 uint8_t op4 = bits(machInst, 4, 0); 510 if (op2 != 0x1f || op3 != 0x0 || op4 != 0x0) 511 return new Unknown64(machInst); 512 switch (opc) { 513 case 0x0: 514 return new Br64(machInst, rn); 515 case 0x1: 516 return new Blr64(machInst, rn); 517 case 0x2: 518 return new Ret64(machInst, rn); 519 case 0x4: 520 if (rn != 0x1f) 521 return new Unknown64(machInst); 522 return new Eret64(machInst); 523 case 0x5: 524 if (rn != 0x1f) 525 return new Unknown64(machInst); 526 return new FailUnimplemented("dret", machInst); 527 default: 528 return new Unknown64(machInst); 529 } 530 } 531 M5_FALLTHROUGH; 532 default: 533 return new Unknown64(machInst); 534 } 535 return new FailUnimplemented("Unhandled Case7", machInst); 536 } 537} 538}}; 539 540output decoder {{ 541namespace Aarch64 542{ 543 StaticInstPtr 544 decodeLoadsStores(ExtMachInst machInst) 545 { 546 // bit 27,25=10 547 switch (bits(machInst, 29, 28)) { 548 case 0x0: 549 if (bits(machInst, 26) == 0) { 550 if (bits(machInst, 24) != 0) 551 return new Unknown64(machInst); 552 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 553 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 554 IntRegIndex rnsp = makeSP(rn); 555 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 556 IntRegIndex rs = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 557 uint8_t opc = (bits(machInst, 15) << 0) | 558 (bits(machInst, 23, 21) << 1); 559 uint8_t size = bits(machInst, 31, 30); 560 switch (opc) { 561 case 0x0: 562 switch (size) { 563 case 0x0: 564 return new STXRB64(machInst, rt, rnsp, rs); 565 case 0x1: 566 return new STXRH64(machInst, rt, rnsp, rs); 567 case 0x2: 568 return new STXRW64(machInst, rt, rnsp, rs); 569 case 0x3: 570 return new STXRX64(machInst, rt, rnsp, rs); 571 default: 572 M5_UNREACHABLE; 573 } 574 case 0x1: 575 switch (size) { 576 case 0x0: 577 return new STLXRB64(machInst, rt, rnsp, rs); 578 case 0x1: 579 return new STLXRH64(machInst, rt, rnsp, rs); 580 case 0x2: 581 return new STLXRW64(machInst, rt, rnsp, rs); 582 case 0x3: 583 return new STLXRX64(machInst, rt, rnsp, rs); 584 default: 585 M5_UNREACHABLE; 586 } 587 case 0x2: 588 switch (size) { 589 case 0x0: 590 case 0x1: 591 return new Unknown64(machInst); 592 case 0x2: 593 return new STXPW64(machInst, rs, rt, rt2, rnsp); 594 case 0x3: 595 return new STXPX64(machInst, rs, rt, rt2, rnsp); 596 default: 597 M5_UNREACHABLE; 598 } 599 600 case 0x3: 601 switch (size) { 602 case 0x0: 603 case 0x1: 604 return new Unknown64(machInst); 605 case 0x2: 606 return new STLXPW64(machInst, rs, rt, rt2, rnsp); 607 case 0x3: 608 return new STLXPX64(machInst, rs, rt, rt2, rnsp); 609 default: 610 M5_UNREACHABLE; 611 } 612 613 case 0x4: 614 switch (size) { 615 case 0x0: 616 return new LDXRB64(machInst, rt, rnsp, rs); 617 case 0x1: 618 return new LDXRH64(machInst, rt, rnsp, rs); 619 case 0x2: 620 return new LDXRW64(machInst, rt, rnsp, rs); 621 case 0x3: 622 return new LDXRX64(machInst, rt, rnsp, rs); 623 default: 624 M5_UNREACHABLE; 625 } 626 case 0x5: 627 switch (size) { 628 case 0x0: 629 return new LDAXRB64(machInst, rt, rnsp, rs); 630 case 0x1: 631 return new LDAXRH64(machInst, rt, rnsp, rs); 632 case 0x2: 633 return new LDAXRW64(machInst, rt, rnsp, rs); 634 case 0x3: 635 return new LDAXRX64(machInst, rt, rnsp, rs); 636 default: 637 M5_UNREACHABLE; 638 } 639 case 0x6: 640 switch (size) { 641 case 0x0: 642 case 0x1: 643 return new Unknown64(machInst); 644 case 0x2: 645 return new LDXPW64(machInst, rt, rt2, rnsp); 646 case 0x3: 647 return new LDXPX64(machInst, rt, rt2, rnsp); 648 default: 649 M5_UNREACHABLE; 650 } 651 652 case 0x7: 653 switch (size) { 654 case 0x0: 655 case 0x1: 656 return new Unknown64(machInst); 657 case 0x2: 658 return new LDAXPW64(machInst, rt, rt2, rnsp); 659 case 0x3: 660 return new LDAXPX64(machInst, rt, rt2, rnsp); 661 default: 662 M5_UNREACHABLE; 663 } 664 665 case 0x9: 666 switch (size) { 667 case 0x0: 668 return new STLRB64(machInst, rt, rnsp); 669 case 0x1: 670 return new STLRH64(machInst, rt, rnsp); 671 case 0x2: 672 return new STLRW64(machInst, rt, rnsp); 673 case 0x3: 674 return new STLRX64(machInst, rt, rnsp); 675 default: 676 M5_UNREACHABLE; 677 } 678 case 0xd: 679 switch (size) { 680 case 0x0: 681 return new LDARB64(machInst, rt, rnsp); 682 case 0x1: 683 return new LDARH64(machInst, rt, rnsp); 684 case 0x2: 685 return new LDARW64(machInst, rt, rnsp); 686 case 0x3: 687 return new LDARX64(machInst, rt, rnsp); 688 default: 689 M5_UNREACHABLE; 690 } 691 default: 692 return new Unknown64(machInst); 693 } 694 } else if (bits(machInst, 31)) { 695 return new Unknown64(machInst); 696 } else { 697 return decodeNeonMem(machInst); 698 } 699 case 0x1: 700 { 701 if (bits(machInst, 24) != 0) 702 return new Unknown64(machInst); 703 uint8_t switchVal = (bits(machInst, 26) << 0) | 704 (bits(machInst, 31, 30) << 1); 705 int64_t imm = sext<19>(bits(machInst, 23, 5)) << 2; 706 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 707 switch (switchVal) { 708 case 0x0: 709 return new LDRWL64_LIT(machInst, rt, imm); 710 case 0x1: 711 return new LDRSFP64_LIT(machInst, rt, imm); 712 case 0x2: 713 return new LDRXL64_LIT(machInst, rt, imm); 714 case 0x3: 715 return new LDRDFP64_LIT(machInst, rt, imm); 716 case 0x4: 717 return new LDRSWL64_LIT(machInst, rt, imm); 718 case 0x5: 719 return new BigFpMemLit("ldr", machInst, rt, imm); 720 case 0x6: 721 return new PRFM64_LIT(machInst, rt, imm); 722 default: 723 return new Unknown64(machInst); 724 } 725 } 726 case 0x2: 727 { 728 uint8_t opc = bits(machInst, 31, 30); 729 if (opc >= 3) 730 return new Unknown64(machInst); 731 uint32_t size = 0; 732 bool fp = bits(machInst, 26); 733 bool load = bits(machInst, 22); 734 if (fp) { 735 size = 4 << opc; 736 } else { 737 if ((opc == 1) && !load) 738 return new Unknown64(machInst); 739 size = (opc == 0 || opc == 1) ? 4 : 8; 740 } 741 uint8_t type = bits(machInst, 24, 23); 742 int64_t imm = sext<7>(bits(machInst, 21, 15)) * size; 743 744 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 745 IntRegIndex rt = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 746 IntRegIndex rt2 = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 747 748 bool noAlloc = (type == 0); 749 bool signExt = !noAlloc && !fp && opc == 1; 750 PairMemOp::AddrMode mode; 751 const char *mnemonic = NULL; 752 switch (type) { 753 case 0x0: 754 case 0x2: 755 mode = PairMemOp::AddrMd_Offset; 756 break; 757 case 0x1: 758 mode = PairMemOp::AddrMd_PostIndex; 759 break; 760 case 0x3: 761 mode = PairMemOp::AddrMd_PreIndex; 762 break; 763 default: 764 return new Unknown64(machInst); 765 } 766 if (load) { 767 if (noAlloc) 768 mnemonic = "ldnp"; 769 else if (signExt) 770 mnemonic = "ldpsw"; 771 else 772 mnemonic = "ldp"; 773 } else { 774 if (noAlloc) 775 mnemonic = "stnp"; 776 else 777 mnemonic = "stp"; 778 } 779 780 return new LdpStp(mnemonic, machInst, size, fp, load, noAlloc, 781 signExt, false, false, imm, mode, rn, rt, rt2); 782 } 783 // bit 29:27=111, 25=0 784 case 0x3: 785 { 786 uint8_t switchVal = (bits(machInst, 23, 22) << 0) | 787 (bits(machInst, 26) << 2) | 788 (bits(machInst, 31, 30) << 3); 789 if (bits(machInst, 24) == 1) { 790 uint64_t imm12 = bits(machInst, 21, 10); 791 IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 792 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 793 IntRegIndex rnsp = makeSP(rn); 794 switch (switchVal) { 795 case 0x00: 796 return new STRB64_IMM(machInst, rt, rnsp, imm12); 797 case 0x01: 798 return new LDRB64_IMM(machInst, rt, rnsp, imm12); 799 case 0x02: 800 return new LDRSBX64_IMM(machInst, rt, rnsp, imm12); 801 case 0x03: 802 return new LDRSBW64_IMM(machInst, rt, rnsp, imm12); 803 case 0x04: 804 return new STRBFP64_IMM(machInst, rt, rnsp, imm12); 805 case 0x05: 806 return new LDRBFP64_IMM(machInst, rt, rnsp, imm12); 807 case 0x06: 808 return new BigFpMemImm("str", machInst, false, 809 rt, rnsp, imm12 << 4); 810 case 0x07: 811 return new BigFpMemImm("ldr", machInst, true, 812 rt, rnsp, imm12 << 4); 813 case 0x08: 814 return new STRH64_IMM(machInst, rt, rnsp, imm12 << 1); 815 case 0x09: 816 return new LDRH64_IMM(machInst, rt, rnsp, imm12 << 1); 817 case 0x0a: 818 return new LDRSHX64_IMM(machInst, rt, rnsp, imm12 << 1); 819 case 0x0b: 820 return new LDRSHW64_IMM(machInst, rt, rnsp, imm12 << 1); 821 case 0x0c: 822 return new STRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 823 case 0x0d: 824 return new LDRHFP64_IMM(machInst, rt, rnsp, imm12 << 1); 825 case 0x10: 826 return new STRW64_IMM(machInst, rt, rnsp, imm12 << 2); 827 case 0x11: 828 return new LDRW64_IMM(machInst, rt, rnsp, imm12 << 2); 829 case 0x12: 830 return new LDRSW64_IMM(machInst, rt, rnsp, imm12 << 2); 831 case 0x14: 832 return new STRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 833 case 0x15: 834 return new LDRSFP64_IMM(machInst, rt, rnsp, imm12 << 2); 835 case 0x18: 836 return new STRX64_IMM(machInst, rt, rnsp, imm12 << 3); 837 case 0x19: 838 return new LDRX64_IMM(machInst, rt, rnsp, imm12 << 3); 839 case 0x1a: 840 return new PRFM64_IMM(machInst, rt, rnsp, imm12 << 3); 841 case 0x1c: 842 return new STRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 843 case 0x1d: 844 return new LDRDFP64_IMM(machInst, rt, rnsp, imm12 << 3); 845 default: 846 return new Unknown64(machInst); 847 } 848 } else if (bits(machInst, 21) == 1) { 849 uint8_t group = bits(machInst, 11, 10); 850 switch (group) { 851 case 0x0: 852 { 853 if ((switchVal & 0x7) == 0x2 && 854 bits(machInst, 20, 12) == 0x1fc) { 855 IntRegIndex rt = (IntRegIndex)(uint32_t) 856 bits(machInst, 4, 0); 857 IntRegIndex rn = (IntRegIndex)(uint32_t) 858 bits(machInst, 9, 5); 859 IntRegIndex rnsp = makeSP(rn); 860 uint8_t size = bits(machInst, 31, 30); 861 switch (size) { 862 case 0x0: 863 return new LDAPRB64(machInst, rt, rnsp); 864 case 0x1: 865 return new LDAPRH64(machInst, rt, rnsp); 866 case 0x2: 867 return new LDAPRW64(machInst, rt, rnsp); 868 case 0x3: 869 return new LDAPRX64(machInst, rt, rnsp); 870 default: 871 M5_UNREACHABLE; 872 } 873 } else { 874 return new Unknown64(machInst); 875 } 876 } 877 case 0x2: 878 { 879 if (!bits(machInst, 14)) 880 return new Unknown64(machInst); 881 IntRegIndex rt = (IntRegIndex)(uint32_t) 882 bits(machInst, 4, 0); 883 IntRegIndex rn = (IntRegIndex)(uint32_t) 884 bits(machInst, 9, 5); 885 IntRegIndex rnsp = makeSP(rn); 886 IntRegIndex rm = (IntRegIndex)(uint32_t) 887 bits(machInst, 20, 16); 888 ArmExtendType type = 889 (ArmExtendType)(uint32_t)bits(machInst, 15, 13); 890 uint8_t s = bits(machInst, 12); 891 switch (switchVal) { 892 case 0x00: 893 return new STRB64_REG(machInst, rt, rnsp, rm, 894 type, 0); 895 case 0x01: 896 return new LDRB64_REG(machInst, rt, rnsp, rm, 897 type, 0); 898 case 0x02: 899 return new LDRSBX64_REG(machInst, rt, rnsp, rm, 900 type, 0); 901 case 0x03: 902 return new LDRSBW64_REG(machInst, rt, rnsp, rm, 903 type, 0); 904 case 0x04: 905 return new STRBFP64_REG(machInst, rt, rnsp, rm, 906 type, 0); 907 case 0x05: 908 return new LDRBFP64_REG(machInst, rt, rnsp, rm, 909 type, 0); 910 case 0x6: 911 return new BigFpMemReg("str", machInst, false, 912 rt, rnsp, rm, type, s * 4); 913 case 0x7: 914 return new BigFpMemReg("ldr", machInst, true, 915 rt, rnsp, rm, type, s * 4); 916 case 0x08: 917 return new STRH64_REG(machInst, rt, rnsp, rm, 918 type, s); 919 case 0x09: 920 return new LDRH64_REG(machInst, rt, rnsp, rm, 921 type, s); 922 case 0x0a: 923 return new LDRSHX64_REG(machInst, rt, rnsp, rm, 924 type, s); 925 case 0x0b: 926 return new LDRSHW64_REG(machInst, rt, rnsp, rm, 927 type, s); 928 case 0x0c: 929 return new STRHFP64_REG(machInst, rt, rnsp, rm, 930 type, s); 931 case 0x0d: 932 return new LDRHFP64_REG(machInst, rt, rnsp, rm, 933 type, s); 934 case 0x10: 935 return new STRW64_REG(machInst, rt, rnsp, rm, 936 type, s * 2); 937 case 0x11: 938 return new LDRW64_REG(machInst, rt, rnsp, rm, 939 type, s * 2); 940 case 0x12: 941 return new LDRSW64_REG(machInst, rt, rnsp, rm, 942 type, s * 2); 943 case 0x14: 944 return new STRSFP64_REG(machInst, rt, rnsp, rm, 945 type, s * 2); 946 case 0x15: 947 return new LDRSFP64_REG(machInst, rt, rnsp, rm, 948 type, s * 2); 949 case 0x18: 950 return new STRX64_REG(machInst, rt, rnsp, rm, 951 type, s * 3); 952 case 0x19: 953 return new LDRX64_REG(machInst, rt, rnsp, rm, 954 type, s * 3); 955 case 0x1a: 956 return new PRFM64_REG(machInst, rt, rnsp, rm, 957 type, s * 3); 958 case 0x1c: 959 return new STRDFP64_REG(machInst, rt, rnsp, rm, 960 type, s * 3); 961 case 0x1d: 962 return new LDRDFP64_REG(machInst, rt, rnsp, rm, 963 type, s * 3); 964 default: 965 return new Unknown64(machInst); 966 967 } 968 } 969 default: 970 return new Unknown64(machInst); 971 } 972 } else { 973 // bit 29:27=111, 25:24=00, 21=0 974 switch (bits(machInst, 11, 10)) { 975 case 0x0: 976 { 977 IntRegIndex rt = 978 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 979 IntRegIndex rn = 980 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 981 IntRegIndex rnsp = makeSP(rn); 982 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 983 switch (switchVal) { 984 case 0x00: 985 return new STURB64_IMM(machInst, rt, rnsp, imm); 986 case 0x01: 987 return new LDURB64_IMM(machInst, rt, rnsp, imm); 988 case 0x02: 989 return new LDURSBX64_IMM(machInst, rt, rnsp, imm); 990 case 0x03: 991 return new LDURSBW64_IMM(machInst, rt, rnsp, imm); 992 case 0x04: 993 return new STURBFP64_IMM(machInst, rt, rnsp, imm); 994 case 0x05: 995 return new LDURBFP64_IMM(machInst, rt, rnsp, imm); 996 case 0x06: 997 return new BigFpMemImm("stur", machInst, false, 998 rt, rnsp, imm); 999 case 0x07: 1000 return new BigFpMemImm("ldur", machInst, true, 1001 rt, rnsp, imm); 1002 case 0x08: 1003 return new STURH64_IMM(machInst, rt, rnsp, imm); 1004 case 0x09: 1005 return new LDURH64_IMM(machInst, rt, rnsp, imm); 1006 case 0x0a: 1007 return new LDURSHX64_IMM(machInst, rt, rnsp, imm); 1008 case 0x0b: 1009 return new LDURSHW64_IMM(machInst, rt, rnsp, imm); 1010 case 0x0c: 1011 return new STURHFP64_IMM(machInst, rt, rnsp, imm); 1012 case 0x0d: 1013 return new LDURHFP64_IMM(machInst, rt, rnsp, imm); 1014 case 0x10: 1015 return new STURW64_IMM(machInst, rt, rnsp, imm); 1016 case 0x11: 1017 return new LDURW64_IMM(machInst, rt, rnsp, imm); 1018 case 0x12: 1019 return new LDURSW64_IMM(machInst, rt, rnsp, imm); 1020 case 0x14: 1021 return new STURSFP64_IMM(machInst, rt, rnsp, imm); 1022 case 0x15: 1023 return new LDURSFP64_IMM(machInst, rt, rnsp, imm); 1024 case 0x18: 1025 return new STURX64_IMM(machInst, rt, rnsp, imm); 1026 case 0x19: 1027 return new LDURX64_IMM(machInst, rt, rnsp, imm); 1028 case 0x1a: 1029 return new PRFUM64_IMM(machInst, rt, rnsp, imm); 1030 case 0x1c: 1031 return new STURDFP64_IMM(machInst, rt, rnsp, imm); 1032 case 0x1d: 1033 return new LDURDFP64_IMM(machInst, rt, rnsp, imm); 1034 default: 1035 return new Unknown64(machInst); 1036 } 1037 } 1038 // bit 29:27=111, 25:24=00, 21=0, 11:10=01 1039 case 0x1: 1040 { 1041 IntRegIndex rt = 1042 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1043 IntRegIndex rn = 1044 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1045 IntRegIndex rnsp = makeSP(rn); 1046 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1047 switch (switchVal) { 1048 case 0x00: 1049 return new STRB64_POST(machInst, rt, rnsp, imm); 1050 case 0x01: 1051 return new LDRB64_POST(machInst, rt, rnsp, imm); 1052 case 0x02: 1053 return new LDRSBX64_POST(machInst, rt, rnsp, imm); 1054 case 0x03: 1055 return new LDRSBW64_POST(machInst, rt, rnsp, imm); 1056 case 0x04: 1057 return new STRBFP64_POST(machInst, rt, rnsp, imm); 1058 case 0x05: 1059 return new LDRBFP64_POST(machInst, rt, rnsp, imm); 1060 case 0x06: 1061 return new BigFpMemPost("str", machInst, false, 1062 rt, rnsp, imm); 1063 case 0x07: 1064 return new BigFpMemPost("ldr", machInst, true, 1065 rt, rnsp, imm); 1066 case 0x08: 1067 return new STRH64_POST(machInst, rt, rnsp, imm); 1068 case 0x09: 1069 return new LDRH64_POST(machInst, rt, rnsp, imm); 1070 case 0x0a: 1071 return new LDRSHX64_POST(machInst, rt, rnsp, imm); 1072 case 0x0b: 1073 return new LDRSHW64_POST(machInst, rt, rnsp, imm); 1074 case 0x0c: 1075 return new STRHFP64_POST(machInst, rt, rnsp, imm); 1076 case 0x0d: 1077 return new LDRHFP64_POST(machInst, rt, rnsp, imm); 1078 case 0x10: 1079 return new STRW64_POST(machInst, rt, rnsp, imm); 1080 case 0x11: 1081 return new LDRW64_POST(machInst, rt, rnsp, imm); 1082 case 0x12: 1083 return new LDRSW64_POST(machInst, rt, rnsp, imm); 1084 case 0x14: 1085 return new STRSFP64_POST(machInst, rt, rnsp, imm); 1086 case 0x15: 1087 return new LDRSFP64_POST(machInst, rt, rnsp, imm); 1088 case 0x18: 1089 return new STRX64_POST(machInst, rt, rnsp, imm); 1090 case 0x19: 1091 return new LDRX64_POST(machInst, rt, rnsp, imm); 1092 case 0x1c: 1093 return new STRDFP64_POST(machInst, rt, rnsp, imm); 1094 case 0x1d: 1095 return new LDRDFP64_POST(machInst, rt, rnsp, imm); 1096 default: 1097 return new Unknown64(machInst); 1098 } 1099 } 1100 case 0x2: 1101 { 1102 IntRegIndex rt = 1103 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1104 IntRegIndex rn = 1105 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1106 IntRegIndex rnsp = makeSP(rn); 1107 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1108 switch (switchVal) { 1109 case 0x00: 1110 return new STTRB64_IMM(machInst, rt, rnsp, imm); 1111 case 0x01: 1112 return new LDTRB64_IMM(machInst, rt, rnsp, imm); 1113 case 0x02: 1114 return new LDTRSBX64_IMM(machInst, rt, rnsp, imm); 1115 case 0x03: 1116 return new LDTRSBW64_IMM(machInst, rt, rnsp, imm); 1117 case 0x08: 1118 return new STTRH64_IMM(machInst, rt, rnsp, imm); 1119 case 0x09: 1120 return new LDTRH64_IMM(machInst, rt, rnsp, imm); 1121 case 0x0a: 1122 return new LDTRSHX64_IMM(machInst, rt, rnsp, imm); 1123 case 0x0b: 1124 return new LDTRSHW64_IMM(machInst, rt, rnsp, imm); 1125 case 0x10: 1126 return new STTRW64_IMM(machInst, rt, rnsp, imm); 1127 case 0x11: 1128 return new LDTRW64_IMM(machInst, rt, rnsp, imm); 1129 case 0x12: 1130 return new LDTRSW64_IMM(machInst, rt, rnsp, imm); 1131 case 0x18: 1132 return new STTRX64_IMM(machInst, rt, rnsp, imm); 1133 case 0x19: 1134 return new LDTRX64_IMM(machInst, rt, rnsp, imm); 1135 default: 1136 return new Unknown64(machInst); 1137 } 1138 } 1139 case 0x3: 1140 { 1141 IntRegIndex rt = 1142 (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1143 IntRegIndex rn = 1144 (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1145 IntRegIndex rnsp = makeSP(rn); 1146 uint64_t imm = sext<9>(bits(machInst, 20, 12)); 1147 switch (switchVal) { 1148 case 0x00: 1149 return new STRB64_PRE(machInst, rt, rnsp, imm); 1150 case 0x01: 1151 return new LDRB64_PRE(machInst, rt, rnsp, imm); 1152 case 0x02: 1153 return new LDRSBX64_PRE(machInst, rt, rnsp, imm); 1154 case 0x03: 1155 return new LDRSBW64_PRE(machInst, rt, rnsp, imm); 1156 case 0x04: 1157 return new STRBFP64_PRE(machInst, rt, rnsp, imm); 1158 case 0x05: 1159 return new LDRBFP64_PRE(machInst, rt, rnsp, imm); 1160 case 0x06: 1161 return new BigFpMemPre("str", machInst, false, 1162 rt, rnsp, imm); 1163 case 0x07: 1164 return new BigFpMemPre("ldr", machInst, true, 1165 rt, rnsp, imm); 1166 case 0x08: 1167 return new STRH64_PRE(machInst, rt, rnsp, imm); 1168 case 0x09: 1169 return new LDRH64_PRE(machInst, rt, rnsp, imm); 1170 case 0x0a: 1171 return new LDRSHX64_PRE(machInst, rt, rnsp, imm); 1172 case 0x0b: 1173 return new LDRSHW64_PRE(machInst, rt, rnsp, imm); 1174 case 0x0c: 1175 return new STRHFP64_PRE(machInst, rt, rnsp, imm); 1176 case 0x0d: 1177 return new LDRHFP64_PRE(machInst, rt, rnsp, imm); 1178 case 0x10: 1179 return new STRW64_PRE(machInst, rt, rnsp, imm); 1180 case 0x11: 1181 return new LDRW64_PRE(machInst, rt, rnsp, imm); 1182 case 0x12: 1183 return new LDRSW64_PRE(machInst, rt, rnsp, imm); 1184 case 0x14: 1185 return new STRSFP64_PRE(machInst, rt, rnsp, imm); 1186 case 0x15: 1187 return new LDRSFP64_PRE(machInst, rt, rnsp, imm); 1188 case 0x18: 1189 return new STRX64_PRE(machInst, rt, rnsp, imm); 1190 case 0x19: 1191 return new LDRX64_PRE(machInst, rt, rnsp, imm); 1192 case 0x1c: 1193 return new STRDFP64_PRE(machInst, rt, rnsp, imm); 1194 case 0x1d: 1195 return new LDRDFP64_PRE(machInst, rt, rnsp, imm); 1196 default: 1197 return new Unknown64(machInst); 1198 } 1199 } 1200 default: 1201 M5_UNREACHABLE; 1202 } 1203 } 1204 } 1205 default: 1206 M5_UNREACHABLE; 1207 } 1208 return new FailUnimplemented("Unhandled Case1", machInst); 1209 } 1210} 1211}}; 1212 1213output decoder {{ 1214namespace Aarch64 1215{ 1216 StaticInstPtr 1217 decodeDataProcReg(ExtMachInst machInst) 1218 { 1219 uint8_t switchVal = (bits(machInst, 28) << 1) | 1220 (bits(machInst, 24) << 0); 1221 switch (switchVal) { 1222 case 0x0: 1223 { 1224 uint8_t switchVal = (bits(machInst, 21) << 0) | 1225 (bits(machInst, 30, 29) << 1); 1226 ArmShiftType type = (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1227 uint8_t imm6 = bits(machInst, 15, 10); 1228 bool sf = bits(machInst, 31); 1229 if (!sf && (imm6 & 0x20)) 1230 return new Unknown64(machInst); 1231 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1232 IntRegIndex rdzr = makeZero(rd); 1233 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1234 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1235 1236 switch (switchVal) { 1237 case 0x0: 1238 return new AndXSReg(machInst, rdzr, rn, rm, imm6, type); 1239 case 0x1: 1240 return new BicXSReg(machInst, rdzr, rn, rm, imm6, type); 1241 case 0x2: 1242 return new OrrXSReg(machInst, rdzr, rn, rm, imm6, type); 1243 case 0x3: 1244 return new OrnXSReg(machInst, rdzr, rn, rm, imm6, type); 1245 case 0x4: 1246 return new EorXSReg(machInst, rdzr, rn, rm, imm6, type); 1247 case 0x5: 1248 return new EonXSReg(machInst, rdzr, rn, rm, imm6, type); 1249 case 0x6: 1250 return new AndXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1251 case 0x7: 1252 return new BicXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1253 default: 1254 M5_UNREACHABLE; 1255 } 1256 } 1257 case 0x1: 1258 { 1259 uint8_t switchVal = bits(machInst, 30, 29); 1260 if (bits(machInst, 21) == 0) { 1261 ArmShiftType type = 1262 (ArmShiftType)(uint8_t)bits(machInst, 23, 22); 1263 if (type == ROR) 1264 return new Unknown64(machInst); 1265 uint8_t imm6 = bits(machInst, 15, 10); 1266 if (!bits(machInst, 31) && bits(imm6, 5)) 1267 return new Unknown64(machInst); 1268 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1269 IntRegIndex rdzr = makeZero(rd); 1270 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1271 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1272 switch (switchVal) { 1273 case 0x0: 1274 return new AddXSReg(machInst, rdzr, rn, rm, imm6, type); 1275 case 0x1: 1276 return new AddXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1277 case 0x2: 1278 return new SubXSReg(machInst, rdzr, rn, rm, imm6, type); 1279 case 0x3: 1280 return new SubXSRegCc(machInst, rdzr, rn, rm, imm6, type); 1281 default: 1282 M5_UNREACHABLE; 1283 } 1284 } else { 1285 if (bits(machInst, 23, 22) != 0 || bits(machInst, 12, 10) > 0x4) 1286 return new Unknown64(machInst); 1287 ArmExtendType type = 1288 (ArmExtendType)(uint8_t)bits(machInst, 15, 13); 1289 uint8_t imm3 = bits(machInst, 12, 10); 1290 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1291 IntRegIndex rdsp = makeSP(rd); 1292 IntRegIndex rdzr = makeZero(rd); 1293 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1294 IntRegIndex rnsp = makeSP(rn); 1295 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1296 1297 switch (switchVal) { 1298 case 0x0: 1299 return new AddXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1300 case 0x1: 1301 return new AddXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1302 case 0x2: 1303 return new SubXEReg(machInst, rdsp, rnsp, rm, type, imm3); 1304 case 0x3: 1305 return new SubXERegCc(machInst, rdzr, rnsp, rm, type, imm3); 1306 default: 1307 M5_UNREACHABLE; 1308 } 1309 } 1310 } 1311 case 0x2: 1312 { 1313 if (bits(machInst, 21) == 1) 1314 return new Unknown64(machInst); 1315 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1316 IntRegIndex rdzr = makeZero(rd); 1317 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1318 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1319 switch (bits(machInst, 23, 22)) { 1320 case 0x0: 1321 { 1322 if (bits(machInst, 15, 10)) 1323 return new Unknown64(machInst); 1324 uint8_t switchVal = bits(machInst, 30, 29); 1325 switch (switchVal) { 1326 case 0x0: 1327 return new AdcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1328 case 0x1: 1329 return new AdcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1330 case 0x2: 1331 return new SbcXSReg(machInst, rdzr, rn, rm, 0, LSL); 1332 case 0x3: 1333 return new SbcXSRegCc(machInst, rdzr, rn, rm, 0, LSL); 1334 default: 1335 M5_UNREACHABLE; 1336 } 1337 } 1338 case 0x1: 1339 { 1340 if ((bits(machInst, 4) == 1) || 1341 (bits(machInst, 10) == 1) || 1342 (bits(machInst, 29) == 0)) { 1343 return new Unknown64(machInst); 1344 } 1345 ConditionCode cond = 1346 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1347 uint8_t flags = bits(machInst, 3, 0); 1348 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1349 if (bits(machInst, 11) == 0) { 1350 IntRegIndex rm = 1351 (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1352 if (bits(machInst, 30) == 0) { 1353 return new CcmnReg64(machInst, rn, rm, cond, flags); 1354 } else { 1355 return new CcmpReg64(machInst, rn, rm, cond, flags); 1356 } 1357 } else { 1358 uint8_t imm5 = bits(machInst, 20, 16); 1359 if (bits(machInst, 30) == 0) { 1360 return new CcmnImm64(machInst, rn, imm5, cond, flags); 1361 } else { 1362 return new CcmpImm64(machInst, rn, imm5, cond, flags); 1363 } 1364 } 1365 } 1366 case 0x2: 1367 { 1368 if (bits(machInst, 29) == 1 || 1369 bits(machInst, 11) == 1) { 1370 return new Unknown64(machInst); 1371 } 1372 uint8_t switchVal = (bits(machInst, 10) << 0) | 1373 (bits(machInst, 30) << 1); 1374 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1375 IntRegIndex rdzr = makeZero(rd); 1376 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1377 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1378 ConditionCode cond = 1379 (ConditionCode)(uint8_t)bits(machInst, 15, 12); 1380 switch (switchVal) { 1381 case 0x0: 1382 return new Csel64(machInst, rdzr, rn, rm, cond); 1383 case 0x1: 1384 return new Csinc64(machInst, rdzr, rn, rm, cond); 1385 case 0x2: 1386 return new Csinv64(machInst, rdzr, rn, rm, cond); 1387 case 0x3: 1388 return new Csneg64(machInst, rdzr, rn, rm, cond); 1389 default: 1390 M5_UNREACHABLE; 1391 } 1392 } 1393 case 0x3: 1394 if (bits(machInst, 30) == 0) { 1395 if (bits(machInst, 29) != 0) 1396 return new Unknown64(machInst); 1397 uint8_t switchVal = bits(machInst, 15, 10); 1398 switch (switchVal) { 1399 case 0x2: 1400 return new Udiv64(machInst, rdzr, rn, rm); 1401 case 0x3: 1402 return new Sdiv64(machInst, rdzr, rn, rm); 1403 case 0x8: 1404 return new Lslv64(machInst, rdzr, rn, rm); 1405 case 0x9: 1406 return new Lsrv64(machInst, rdzr, rn, rm); 1407 case 0xa: 1408 return new Asrv64(machInst, rdzr, rn, rm); 1409 case 0xb: 1410 return new Rorv64(machInst, rdzr, rn, rm); 1411 case 0x10: 1412 return new Crc32b64(machInst, rdzr, rn, rm); 1413 case 0x11: 1414 return new Crc32h64(machInst, rdzr, rn, rm); 1415 case 0x12: 1416 return new Crc32w64(machInst, rdzr, rn, rm); 1417 case 0x13: 1418 return new Crc32x64(machInst, rdzr, rn, rm); 1419 case 0x14: 1420 return new Crc32cb64(machInst, rdzr, rn, rm); 1421 case 0x15: 1422 return new Crc32ch64(machInst, rdzr, rn, rm); 1423 case 0x16: 1424 return new Crc32cw64(machInst, rdzr, rn, rm); 1425 case 0x17: 1426 return new Crc32cx64(machInst, rdzr, rn, rm); 1427 default: 1428 return new Unknown64(machInst); 1429 } 1430 } else { 1431 if (bits(machInst, 20, 16) != 0 || 1432 bits(machInst, 29) != 0) { 1433 return new Unknown64(machInst); 1434 } 1435 uint8_t switchVal = bits(machInst, 15, 10); 1436 switch (switchVal) { 1437 case 0x0: 1438 return new Rbit64(machInst, rdzr, rn); 1439 case 0x1: 1440 return new Rev1664(machInst, rdzr, rn); 1441 case 0x2: 1442 if (bits(machInst, 31) == 0) 1443 return new Rev64(machInst, rdzr, rn); 1444 else 1445 return new Rev3264(machInst, rdzr, rn); 1446 case 0x3: 1447 if (bits(machInst, 31) != 1) 1448 return new Unknown64(machInst); 1449 return new Rev64(machInst, rdzr, rn); 1450 case 0x4: 1451 return new Clz64(machInst, rdzr, rn); 1452 case 0x5: 1453 return new Cls64(machInst, rdzr, rn); 1454 default: 1455 return new Unknown64(machInst); 1456 } 1457 } 1458 default: 1459 M5_UNREACHABLE; 1460 } 1461 } 1462 case 0x3: 1463 { 1464 if (bits(machInst, 30, 29) != 0x0 || 1465 (bits(machInst, 23, 21) != 0 && bits(machInst, 31) == 0)) 1466 return new Unknown64(machInst); 1467 IntRegIndex rd = (IntRegIndex)(uint8_t)bits(machInst, 4, 0); 1468 IntRegIndex rdzr = makeZero(rd); 1469 IntRegIndex rn = (IntRegIndex)(uint8_t)bits(machInst, 9, 5); 1470 IntRegIndex ra = (IntRegIndex)(uint8_t)bits(machInst, 14, 10); 1471 IntRegIndex rm = (IntRegIndex)(uint8_t)bits(machInst, 20, 16); 1472 switch (bits(machInst, 23, 21)) { 1473 case 0x0: 1474 if (bits(machInst, 15) == 0) 1475 return new Madd64(machInst, rdzr, ra, rn, rm); 1476 else 1477 return new Msub64(machInst, rdzr, ra, rn, rm); 1478 case 0x1: 1479 if (bits(machInst, 15) == 0) 1480 return new Smaddl64(machInst, rdzr, ra, rn, rm); 1481 else 1482 return new Smsubl64(machInst, rdzr, ra, rn, rm); 1483 case 0x2: 1484 if (bits(machInst, 15) != 0) 1485 return new Unknown64(machInst); 1486 return new Smulh64(machInst, rdzr, rn, rm); 1487 case 0x5: 1488 if (bits(machInst, 15) == 0) 1489 return new Umaddl64(machInst, rdzr, ra, rn, rm); 1490 else 1491 return new Umsubl64(machInst, rdzr, ra, rn, rm); 1492 case 0x6: 1493 if (bits(machInst, 15) != 0) 1494 return new Unknown64(machInst); 1495 return new Umulh64(machInst, rdzr, rn, rm); 1496 default: 1497 return new Unknown64(machInst); 1498 } 1499 } 1500 default: 1501 M5_UNREACHABLE; 1502 } 1503 return new FailUnimplemented("Unhandled Case2", machInst); 1504 } 1505} 1506}}; 1507 1508output decoder {{ 1509namespace Aarch64 1510{ 1511 template <typename DecoderFeatures> 1512 StaticInstPtr 1513 decodeAdvSIMD(ExtMachInst machInst) 1514 { 1515 if (bits(machInst, 24) == 1) { 1516 if (bits(machInst, 10) == 0) { 1517 return decodeNeonIndexedElem<DecoderFeatures>(machInst); 1518 } else if (bits(machInst, 23) == 1) { 1519 return new Unknown64(machInst); 1520 } else { 1521 if (bits(machInst, 22, 19)) { 1522 return decodeNeonShiftByImm(machInst); 1523 } else { 1524 return decodeNeonModImm(machInst); 1525 } 1526 } 1527 } else if (bits(machInst, 21) == 1) { 1528 if (bits(machInst, 10) == 1) { 1529 return decodeNeon3Same<DecoderFeatures>(machInst); 1530 } else if (bits(machInst, 11) == 0) { 1531 return decodeNeon3Diff(machInst); 1532 } else if (bits(machInst, 20, 17) == 0x0) { 1533 return decodeNeon2RegMisc(machInst); 1534 } else if (bits(machInst, 20, 17) == 0x4) { 1535 return decodeCryptoAES(machInst); 1536 } else if (bits(machInst, 20, 17) == 0x8) { 1537 return decodeNeonAcrossLanes(machInst); 1538 } else { 1539 return new Unknown64(machInst); 1540 } 1541 } else if (bits(machInst, 24) || 1542 bits(machInst, 21) || 1543 bits(machInst, 15)) { 1544 return new Unknown64(machInst); 1545 } else if (bits(machInst, 10) == 1) { 1546 if (bits(machInst, 23, 22)) 1547 return new Unknown64(machInst); 1548 return decodeNeonCopy(machInst); 1549 } else if (bits(machInst, 29) == 1) { 1550 return decodeNeonExt(machInst); 1551 } else if (bits(machInst, 11) == 1) { 1552 return decodeNeonZipUzpTrn(machInst); 1553 } else if (bits(machInst, 23, 22) == 0x0) { 1554 return decodeNeonTblTbx(machInst); 1555 } else { 1556 return new Unknown64(machInst); 1557 } 1558 return new FailUnimplemented("Unhandled Case3", machInst); 1559 } 1560} 1561}}; 1562 1563 1564output decoder {{ 1565namespace Aarch64 1566{ 1567 StaticInstPtr 1568 // bit 30=0, 28:25=1111 1569 decodeFp(ExtMachInst machInst) 1570 { 1571 if (bits(machInst, 24) == 1) { 1572 if (bits(machInst, 31) || bits(machInst, 29)) 1573 return new Unknown64(machInst); 1574 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1575 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1576 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 1577 IntRegIndex ra = (IntRegIndex)(uint32_t)bits(machInst, 14, 10); 1578 uint8_t switchVal = (bits(machInst, 23, 21) << 1) | 1579 (bits(machInst, 15) << 0); 1580 switch (switchVal) { 1581 case 0x0: // FMADD Sd = Sa + Sn*Sm 1582 return new FMAddS(machInst, rd, rn, rm, ra); 1583 case 0x1: // FMSUB Sd = Sa + (-Sn)*Sm 1584 return new FMSubS(machInst, rd, rn, rm, ra); 1585 case 0x2: // FNMADD Sd = (-Sa) + (-Sn)*Sm 1586 return new FNMAddS(machInst, rd, rn, rm, ra); 1587 case 0x3: // FNMSUB Sd = (-Sa) + Sn*Sm 1588 return new FNMSubS(machInst, rd, rn, rm, ra); 1589 case 0x4: // FMADD Dd = Da + Dn*Dm 1590 return new FMAddD(machInst, rd, rn, rm, ra); 1591 case 0x5: // FMSUB Dd = Da + (-Dn)*Dm 1592 return new FMSubD(machInst, rd, rn, rm, ra); 1593 case 0x6: // FNMADD Dd = (-Da) + (-Dn)*Dm 1594 return new FNMAddD(machInst, rd, rn, rm, ra); 1595 case 0x7: // FNMSUB Dd = (-Da) + Dn*Dm 1596 return new FNMSubD(machInst, rd, rn, rm, ra); 1597 default: 1598 return new Unknown64(machInst); 1599 } 1600 } else if (bits(machInst, 21) == 0) { 1601 bool s = bits(machInst, 29); 1602 if (s) 1603 return new Unknown64(machInst); 1604 uint8_t switchVal = bits(machInst, 20, 16); 1605 uint8_t type = bits(machInst, 23, 22); 1606 uint8_t scale = bits(machInst, 15, 10); 1607 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1608 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1609 if (bits(machInst, 18, 17) == 3 && scale != 0) 1610 return new Unknown64(machInst); 1611 // 30:24=0011110, 21=0 1612 switch (switchVal) { 1613 case 0x00: 1614 return new FailUnimplemented("fcvtns", machInst); 1615 case 0x01: 1616 return new FailUnimplemented("fcvtnu", machInst); 1617 case 0x02: 1618 switch ( (bits(machInst, 31) << 2) | type ) { 1619 case 0: // SCVTF Sd = convertFromInt(Wn/(2^fbits)) 1620 return new FcvtSFixedFpSW(machInst, rd, rn, scale); 1621 case 1: // SCVTF Dd = convertFromInt(Wn/(2^fbits)) 1622 return new FcvtSFixedFpDW(machInst, rd, rn, scale); 1623 case 4: // SCVTF Sd = convertFromInt(Xn/(2^fbits)) 1624 return new FcvtSFixedFpSX(machInst, rd, rn, scale); 1625 case 5: // SCVTF Dd = convertFromInt(Xn/(2^fbits)) 1626 return new FcvtSFixedFpDX(machInst, rd, rn, scale); 1627 default: 1628 return new Unknown64(machInst); 1629 } 1630 case 0x03: 1631 switch ( (bits(machInst, 31) << 2) | type ) { 1632 case 0: // UCVTF Sd = convertFromInt(Wn/(2^fbits)) 1633 return new FcvtUFixedFpSW(machInst, rd, rn, scale); 1634 case 1: // UCVTF Dd = convertFromInt(Wn/(2^fbits)) 1635 return new FcvtUFixedFpDW(machInst, rd, rn, scale); 1636 case 4: // UCVTF Sd = convertFromInt(Xn/(2^fbits)) 1637 return new FcvtUFixedFpSX(machInst, rd, rn, scale); 1638 case 5: // UCVTF Dd = convertFromInt(Xn/(2^fbits)) 1639 return new FcvtUFixedFpDX(machInst, rd, rn, scale); 1640 default: 1641 return new Unknown64(machInst); 1642 } 1643 case 0x04: 1644 return new FailUnimplemented("fcvtas", machInst); 1645 case 0x05: 1646 return new FailUnimplemented("fcvtau", machInst); 1647 case 0x08: 1648 return new FailUnimplemented("fcvtps", machInst); 1649 case 0x09: 1650 return new FailUnimplemented("fcvtpu", machInst); 1651 case 0x0e: 1652 return new FailUnimplemented("fmov elem. to 64", machInst); 1653 case 0x0f: 1654 return new FailUnimplemented("fmov 64 bit", machInst); 1655 case 0x10: 1656 return new FailUnimplemented("fcvtms", machInst); 1657 case 0x11: 1658 return new FailUnimplemented("fcvtmu", machInst); 1659 case 0x18: 1660 switch ( (bits(machInst, 31) << 2) | type ) { 1661 case 0: // FCVTZS Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 1662 return new FcvtFpSFixedSW(machInst, rd, rn, scale); 1663 case 1: // FCVTZS Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 1664 return new FcvtFpSFixedDW(machInst, rd, rn, scale); 1665 case 4: // FCVTZS Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 1666 return new FcvtFpSFixedSX(machInst, rd, rn, scale); 1667 case 5: // FCVTZS Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 1668 return new FcvtFpSFixedDX(machInst, rd, rn, scale); 1669 default: 1670 return new Unknown64(machInst); 1671 } 1672 case 0x19: 1673 switch ( (bits(machInst, 31) << 2) | type ) { 1674 case 0: // FCVTZU Wd = convertToIntExactTowardZero(Sn*(2^fbits)) 1675 return new FcvtFpUFixedSW(machInst, rd, rn, scale); 1676 case 1: // FCVTZU Wd = convertToIntExactTowardZero(Dn*(2^fbits)) 1677 return new FcvtFpUFixedDW(machInst, rd, rn, scale); 1678 case 4: // FCVTZU Xd = convertToIntExactTowardZero(Sn*(2^fbits)) 1679 return new FcvtFpUFixedSX(machInst, rd, rn, scale); 1680 case 5: // FCVTZU Xd = convertToIntExactTowardZero(Dn*(2^fbits)) 1681 return new FcvtFpUFixedDX(machInst, rd, rn, scale); 1682 default: 1683 return new Unknown64(machInst); 1684 } 1685 default: 1686 return new Unknown64(machInst); 1687 } 1688 } else { 1689 // 30=0, 28:24=11110, 21=1 1690 uint8_t type = bits(machInst, 23, 22); 1691 uint8_t imm8 = bits(machInst, 20, 13); 1692 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 1693 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 1694 switch (bits(machInst, 11, 10)) { 1695 case 0x0: 1696 if (bits(machInst, 12) == 1) { 1697 if (bits(machInst, 31) || 1698 bits(machInst, 29) || 1699 bits(machInst, 9, 5)) { 1700 return new Unknown64(machInst); 1701 } 1702 // 31:29=000, 28:24=11110, 21=1, 12:10=100 1703 if (type == 0) { 1704 // FMOV S[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,5) 1705 // :imm8<5:0>:Zeros(19) 1706 uint32_t imm = vfp_modified_imm(imm8, 1707 FpDataType::Fp32); 1708 return new FmovImmS(machInst, rd, imm); 1709 } else if (type == 1) { 1710 // FMOV D[d] = imm8<7>:NOT(imm8<6>):Replicate(imm8<6>,8) 1711 // :imm8<5:0>:Zeros(48) 1712 uint64_t imm = vfp_modified_imm(imm8, 1713 FpDataType::Fp64); 1714 return new FmovImmD(machInst, rd, imm); 1715 } else { 1716 return new Unknown64(machInst); 1717 } 1718 } else if (bits(machInst, 13) == 1) { 1719 if (bits(machInst, 31) || 1720 bits(machInst, 29) || 1721 bits(machInst, 15, 14) || 1722 bits(machInst, 23) || 1723 bits(machInst, 2, 0)) { 1724 return new Unknown64(machInst); 1725 } 1726 uint8_t switchVal = (bits(machInst, 4, 3) << 0) | 1727 (bits(machInst, 22) << 2); 1728 IntRegIndex rm = (IntRegIndex)(uint32_t) 1729 bits(machInst, 20, 16); 1730 // 28:23=000111100, 21=1, 15:10=001000, 2:0=000 1731 switch (switchVal) { 1732 case 0x0: 1733 // FCMP flags = compareQuiet(Sn,Sm) 1734 return new FCmpRegS(machInst, rn, rm); 1735 case 0x1: 1736 // FCMP flags = compareQuiet(Sn,0.0) 1737 return new FCmpImmS(machInst, rn, 0); 1738 case 0x2: 1739 // FCMPE flags = compareSignaling(Sn,Sm) 1740 return new FCmpERegS(machInst, rn, rm); 1741 case 0x3: 1742 // FCMPE flags = compareSignaling(Sn,0.0) 1743 return new FCmpEImmS(machInst, rn, 0); 1744 case 0x4: 1745 // FCMP flags = compareQuiet(Dn,Dm) 1746 return new FCmpRegD(machInst, rn, rm); 1747 case 0x5: 1748 // FCMP flags = compareQuiet(Dn,0.0) 1749 return new FCmpImmD(machInst, rn, 0); 1750 case 0x6: 1751 // FCMPE flags = compareSignaling(Dn,Dm) 1752 return new FCmpERegD(machInst, rn, rm); 1753 case 0x7: 1754 // FCMPE flags = compareSignaling(Dn,0.0) 1755 return new FCmpEImmD(machInst, rn, 0); 1756 default: 1757 return new Unknown64(machInst); 1758 } 1759 } else if (bits(machInst, 14) == 1) { 1760 if (bits(machInst, 31) || bits(machInst, 29)) 1761 return new Unknown64(machInst); 1762 uint8_t opcode = bits(machInst, 20, 15); 1763 // Bits 31:24=00011110, 21=1, 14:10=10000 1764 switch (opcode) { 1765 case 0x0: 1766 if (type == 0) 1767 // FMOV Sd = Sn 1768 return new FmovRegS(machInst, rd, rn); 1769 else if (type == 1) 1770 // FMOV Dd = Dn 1771 return new FmovRegD(machInst, rd, rn); 1772 break; 1773 case 0x1: 1774 if (type == 0) 1775 // FABS Sd = abs(Sn) 1776 return new FAbsS(machInst, rd, rn); 1777 else if (type == 1) 1778 // FABS Dd = abs(Dn) 1779 return new FAbsD(machInst, rd, rn); 1780 break; 1781 case 0x2: 1782 if (type == 0) 1783 // FNEG Sd = -Sn 1784 return new FNegS(machInst, rd, rn); 1785 else if (type == 1) 1786 // FNEG Dd = -Dn 1787 return new FNegD(machInst, rd, rn); 1788 break; 1789 case 0x3: 1790 if (type == 0) 1791 // FSQRT Sd = sqrt(Sn) 1792 return new FSqrtS(machInst, rd, rn); 1793 else if (type == 1) 1794 // FSQRT Dd = sqrt(Dn) 1795 return new FSqrtD(machInst, rd, rn); 1796 break; 1797 case 0x4: 1798 if (type == 1) 1799 // FCVT Sd = convertFormat(Dn) 1800 return new FcvtFpDFpS(machInst, rd, rn); 1801 else if (type == 3) 1802 // FCVT Sd = convertFormat(Hn) 1803 return new FcvtFpHFpS(machInst, rd, rn); 1804 break; 1805 case 0x5: 1806 if (type == 0) 1807 // FCVT Dd = convertFormat(Sn) 1808 return new FCvtFpSFpD(machInst, rd, rn); 1809 else if (type == 3) 1810 // FCVT Dd = convertFormat(Hn) 1811 return new FcvtFpHFpD(machInst, rd, rn); 1812 break; 1813 case 0x7: 1814 if (type == 0) 1815 // FCVT Hd = convertFormat(Sn) 1816 return new FcvtFpSFpH(machInst, rd, rn); 1817 else if (type == 1) 1818 // FCVT Hd = convertFormat(Dn) 1819 return new FcvtFpDFpH(machInst, rd, rn); 1820 break; 1821 case 0x8: 1822 if (type == 0) // FRINTN Sd = roundToIntegralTiesToEven(Sn) 1823 return new FRIntNS(machInst, rd, rn); 1824 else if (type == 1) // FRINTN Dd = roundToIntegralTiesToEven(Dn) 1825 return new FRIntND(machInst, rd, rn); 1826 break; 1827 case 0x9: 1828 if (type == 0) // FRINTP Sd = roundToIntegralTowardPlusInf(Sn) 1829 return new FRIntPS(machInst, rd, rn); 1830 else if (type == 1) // FRINTP Dd = roundToIntegralTowardPlusInf(Dn) 1831 return new FRIntPD(machInst, rd, rn); 1832 break; 1833 case 0xa: 1834 if (type == 0) // FRINTM Sd = roundToIntegralTowardMinusInf(Sn) 1835 return new FRIntMS(machInst, rd, rn); 1836 else if (type == 1) // FRINTM Dd = roundToIntegralTowardMinusInf(Dn) 1837 return new FRIntMD(machInst, rd, rn); 1838 break; 1839 case 0xb: 1840 if (type == 0) // FRINTZ Sd = roundToIntegralTowardZero(Sn) 1841 return new FRIntZS(machInst, rd, rn); 1842 else if (type == 1) // FRINTZ Dd = roundToIntegralTowardZero(Dn) 1843 return new FRIntZD(machInst, rd, rn); 1844 break; 1845 case 0xc: 1846 if (type == 0) // FRINTA Sd = roundToIntegralTiesToAway(Sn) 1847 return new FRIntAS(machInst, rd, rn); 1848 else if (type == 1) // FRINTA Dd = roundToIntegralTiesToAway(Dn) 1849 return new FRIntAD(machInst, rd, rn); 1850 break; 1851 case 0xe: 1852 if (type == 0) // FRINTX Sd = roundToIntegralExact(Sn) 1853 return new FRIntXS(machInst, rd, rn); 1854 else if (type == 1) // FRINTX Dd = roundToIntegralExact(Dn) 1855 return new FRIntXD(machInst, rd, rn); 1856 break; 1857 case 0xf: 1858 if (type == 0) // FRINTI Sd = roundToIntegral(Sn) 1859 return new FRIntIS(machInst, rd, rn); 1860 else if (type == 1) // FRINTI Dd = roundToIntegral(Dn) 1861 return new FRIntID(machInst, rd, rn); 1862 break; 1863 default: 1864 return new Unknown64(machInst); 1865 } 1866 return new Unknown64(machInst); 1867 } else if (bits(machInst, 15) == 1) { 1868 return new Unknown64(machInst); 1869 } else { 1870 if (bits(machInst, 29)) 1871 return new Unknown64(machInst); 1872 uint8_t rmode = bits(machInst, 20, 19); 1873 uint8_t switchVal1 = bits(machInst, 18, 16); 1874 uint8_t switchVal2 = (type << 1) | bits(machInst, 31); 1875 // 30:24=0011110, 21=1, 15:10=000000 1876 switch (switchVal1) { 1877 case 0x0: 1878 switch ((switchVal2 << 2) | rmode) { 1879 case 0x0: //FCVTNS Wd = convertToIntExactTiesToEven(Sn) 1880 return new FcvtFpSIntWSN(machInst, rd, rn); 1881 case 0x1: //FCVTPS Wd = convertToIntExactTowardPlusInf(Sn) 1882 return new FcvtFpSIntWSP(machInst, rd, rn); 1883 case 0x2: //FCVTMS Wd = convertToIntExactTowardMinusInf(Sn) 1884 return new FcvtFpSIntWSM(machInst, rd, rn); 1885 case 0x3: //FCVTZS Wd = convertToIntExactTowardZero(Sn) 1886 return new FcvtFpSIntWSZ(machInst, rd, rn); 1887 case 0x4: //FCVTNS Xd = convertToIntExactTiesToEven(Sn) 1888 return new FcvtFpSIntXSN(machInst, rd, rn); 1889 case 0x5: //FCVTPS Xd = convertToIntExactTowardPlusInf(Sn) 1890 return new FcvtFpSIntXSP(machInst, rd, rn); 1891 case 0x6: //FCVTMS Xd = convertToIntExactTowardMinusInf(Sn) 1892 return new FcvtFpSIntXSM(machInst, rd, rn); 1893 case 0x7: //FCVTZS Xd = convertToIntExactTowardZero(Sn) 1894 return new FcvtFpSIntXSZ(machInst, rd, rn); 1895 case 0x8: //FCVTNS Wd = convertToIntExactTiesToEven(Dn) 1896 return new FcvtFpSIntWDN(machInst, rd, rn); 1897 case 0x9: //FCVTPS Wd = convertToIntExactTowardPlusInf(Dn) 1898 return new FcvtFpSIntWDP(machInst, rd, rn); 1899 case 0xA: //FCVTMS Wd = convertToIntExactTowardMinusInf(Dn) 1900 return new FcvtFpSIntWDM(machInst, rd, rn); 1901 case 0xB: //FCVTZS Wd = convertToIntExactTowardZero(Dn) 1902 return new FcvtFpSIntWDZ(machInst, rd, rn); 1903 case 0xC: //FCVTNS Xd = convertToIntExactTiesToEven(Dn) 1904 return new FcvtFpSIntXDN(machInst, rd, rn); 1905 case 0xD: //FCVTPS Xd = convertToIntExactTowardPlusInf(Dn) 1906 return new FcvtFpSIntXDP(machInst, rd, rn); 1907 case 0xE: //FCVTMS Xd = convertToIntExactTowardMinusInf(Dn) 1908 return new FcvtFpSIntXDM(machInst, rd, rn); 1909 case 0xF: //FCVTZS Xd = convertToIntExactTowardZero(Dn) 1910 return new FcvtFpSIntXDZ(machInst, rd, rn); 1911 default: 1912 return new Unknown64(machInst); 1913 } 1914 case 0x1: 1915 switch ((switchVal2 << 2) | rmode) { 1916 case 0x0: //FCVTNU Wd = convertToIntExactTiesToEven(Sn) 1917 return new FcvtFpUIntWSN(machInst, rd, rn); 1918 case 0x1: //FCVTPU Wd = convertToIntExactTowardPlusInf(Sn) 1919 return new FcvtFpUIntWSP(machInst, rd, rn); 1920 case 0x2: //FCVTMU Wd = convertToIntExactTowardMinusInf(Sn) 1921 return new FcvtFpUIntWSM(machInst, rd, rn); 1922 case 0x3: //FCVTZU Wd = convertToIntExactTowardZero(Sn) 1923 return new FcvtFpUIntWSZ(machInst, rd, rn); 1924 case 0x4: //FCVTNU Xd = convertToIntExactTiesToEven(Sn) 1925 return new FcvtFpUIntXSN(machInst, rd, rn); 1926 case 0x5: //FCVTPU Xd = convertToIntExactTowardPlusInf(Sn) 1927 return new FcvtFpUIntXSP(machInst, rd, rn); 1928 case 0x6: //FCVTMU Xd = convertToIntExactTowardMinusInf(Sn) 1929 return new FcvtFpUIntXSM(machInst, rd, rn); 1930 case 0x7: //FCVTZU Xd = convertToIntExactTowardZero(Sn) 1931 return new FcvtFpUIntXSZ(machInst, rd, rn); 1932 case 0x8: //FCVTNU Wd = convertToIntExactTiesToEven(Dn) 1933 return new FcvtFpUIntWDN(machInst, rd, rn); 1934 case 0x9: //FCVTPU Wd = convertToIntExactTowardPlusInf(Dn) 1935 return new FcvtFpUIntWDP(machInst, rd, rn); 1936 case 0xA: //FCVTMU Wd = convertToIntExactTowardMinusInf(Dn) 1937 return new FcvtFpUIntWDM(machInst, rd, rn); 1938 case 0xB: //FCVTZU Wd = convertToIntExactTowardZero(Dn) 1939 return new FcvtFpUIntWDZ(machInst, rd, rn); 1940 case 0xC: //FCVTNU Xd = convertToIntExactTiesToEven(Dn) 1941 return new FcvtFpUIntXDN(machInst, rd, rn); 1942 case 0xD: //FCVTPU Xd = convertToIntExactTowardPlusInf(Dn) 1943 return new FcvtFpUIntXDP(machInst, rd, rn); 1944 case 0xE: //FCVTMU Xd = convertToIntExactTowardMinusInf(Dn) 1945 return new FcvtFpUIntXDM(machInst, rd, rn); 1946 case 0xF: //FCVTZU Xd = convertToIntExactTowardZero(Dn) 1947 return new FcvtFpUIntXDZ(machInst, rd, rn); 1948 default: 1949 return new Unknown64(machInst); 1950 } 1951 case 0x2: 1952 if (rmode != 0) 1953 return new Unknown64(machInst); 1954 switch (switchVal2) { 1955 case 0: // SCVTF Sd = convertFromInt(Wn) 1956 return new FcvtWSIntFpS(machInst, rd, rn); 1957 case 1: // SCVTF Sd = convertFromInt(Xn) 1958 return new FcvtXSIntFpS(machInst, rd, rn); 1959 case 2: // SCVTF Dd = convertFromInt(Wn) 1960 return new FcvtWSIntFpD(machInst, rd, rn); 1961 case 3: // SCVTF Dd = convertFromInt(Xn) 1962 return new FcvtXSIntFpD(machInst, rd, rn); 1963 default: 1964 return new Unknown64(machInst); 1965 } 1966 case 0x3: 1967 switch (switchVal2) { 1968 case 0: // UCVTF Sd = convertFromInt(Wn) 1969 return new FcvtWUIntFpS(machInst, rd, rn); 1970 case 1: // UCVTF Sd = convertFromInt(Xn) 1971 return new FcvtXUIntFpS(machInst, rd, rn); 1972 case 2: // UCVTF Dd = convertFromInt(Wn) 1973 return new FcvtWUIntFpD(machInst, rd, rn); 1974 case 3: // UCVTF Dd = convertFromInt(Xn) 1975 return new FcvtXUIntFpD(machInst, rd, rn); 1976 default: 1977 return new Unknown64(machInst); 1978 } 1979 case 0x4: 1980 if (rmode != 0) 1981 return new Unknown64(machInst); 1982 switch (switchVal2) { 1983 case 0: // FCVTAS Wd = convertToIntExactTiesToAway(Sn) 1984 return new FcvtFpSIntWSA(machInst, rd, rn); 1985 case 1: // FCVTAS Xd = convertToIntExactTiesToAway(Sn) 1986 return new FcvtFpSIntXSA(machInst, rd, rn); 1987 case 2: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 1988 return new FcvtFpSIntWDA(machInst, rd, rn); 1989 case 3: // FCVTAS Wd = convertToIntExactTiesToAway(Dn) 1990 return new FcvtFpSIntXDA(machInst, rd, rn); 1991 default: 1992 return new Unknown64(machInst); 1993 } 1994 case 0x5: 1995 switch (switchVal2) { 1996 case 0: // FCVTAU Wd = convertToIntExactTiesToAway(Sn) 1997 return new FcvtFpUIntWSA(machInst, rd, rn); 1998 case 1: // FCVTAU Xd = convertToIntExactTiesToAway(Sn) 1999 return new FcvtFpUIntXSA(machInst, rd, rn); 2000 case 2: // FCVTAU Wd = convertToIntExactTiesToAway(Dn) 2001 return new FcvtFpUIntWDA(machInst, rd, rn); 2002 case 3: // FCVTAU Xd = convertToIntExactTiesToAway(Dn) 2003 return new FcvtFpUIntXDA(machInst, rd, rn); 2004 default: 2005 return new Unknown64(machInst); 2006 } 2007 case 0x06: 2008 switch (switchVal2) { 2009 case 0: // FMOV Wd = Sn 2010 if (rmode != 0) 2011 return new Unknown64(machInst); 2012 return new FmovRegCoreW(machInst, rd, rn); 2013 case 3: // FMOV Xd = Dn 2014 if (rmode != 0) 2015 return new Unknown64(machInst); 2016 return new FmovRegCoreX(machInst, rd, rn); 2017 case 5: // FMOV Xd = Vn<127:64> 2018 if (rmode != 1) 2019 return new Unknown64(machInst); 2020 return new FmovURegCoreX(machInst, rd, rn); 2021 default: 2022 return new Unknown64(machInst); 2023 } 2024 break; 2025 case 0x07: 2026 switch (switchVal2) { 2027 case 0: // FMOV Sd = Wn 2028 if (rmode != 0) 2029 return new Unknown64(machInst); 2030 return new FmovCoreRegW(machInst, rd, rn); 2031 case 3: // FMOV Xd = Dn 2032 if (rmode != 0) 2033 return new Unknown64(machInst); 2034 return new FmovCoreRegX(machInst, rd, rn); 2035 case 5: // FMOV Xd = Vn<127:64> 2036 if (rmode != 1) 2037 return new Unknown64(machInst); 2038 return new FmovUCoreRegX(machInst, rd, rn); 2039 default: 2040 return new Unknown64(machInst); 2041 } 2042 break; 2043 default: // Warning! missing cases in switch statement above, that still need to be added 2044 return new Unknown64(machInst); 2045 } 2046 } 2047 M5_UNREACHABLE; 2048 case 0x1: 2049 { 2050 if (bits(machInst, 31) || 2051 bits(machInst, 29) || 2052 bits(machInst, 23)) { 2053 return new Unknown64(machInst); 2054 } 2055 IntRegIndex rm = (IntRegIndex)(uint32_t) bits(machInst, 20, 16); 2056 IntRegIndex rn = (IntRegIndex)(uint32_t) bits(machInst, 9, 5); 2057 uint8_t imm = (IntRegIndex)(uint32_t) bits(machInst, 3, 0); 2058 ConditionCode cond = 2059 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 2060 uint8_t switchVal = (bits(machInst, 4) << 0) | 2061 (bits(machInst, 22) << 1); 2062 // 31:23=000111100, 21=1, 11:10=01 2063 switch (switchVal) { 2064 case 0x0: 2065 // FCCMP flags = if cond the compareQuiet(Sn,Sm) else #nzcv 2066 return new FCCmpRegS(machInst, rn, rm, cond, imm); 2067 case 0x1: 2068 // FCCMP flags = if cond then compareSignaling(Sn,Sm) 2069 // else #nzcv 2070 return new FCCmpERegS(machInst, rn, rm, cond, imm); 2071 case 0x2: 2072 // FCCMP flags = if cond then compareQuiet(Dn,Dm) else #nzcv 2073 return new FCCmpRegD(machInst, rn, rm, cond, imm); 2074 case 0x3: 2075 // FCCMP flags = if cond then compareSignaling(Dn,Dm) 2076 // else #nzcv 2077 return new FCCmpERegD(machInst, rn, rm, cond, imm); 2078 default: 2079 return new Unknown64(machInst); 2080 } 2081 } 2082 case 0x2: 2083 { 2084 if (bits(machInst, 31) || 2085 bits(machInst, 29) || 2086 bits(machInst, 23)) { 2087 return new Unknown64(machInst); 2088 } 2089 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2090 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2091 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 2092 uint8_t switchVal = (bits(machInst, 15, 12) << 0) | 2093 (bits(machInst, 22) << 4); 2094 switch (switchVal) { 2095 case 0x00: // FMUL Sd = Sn * Sm 2096 return new FMulS(machInst, rd, rn, rm); 2097 case 0x10: // FMUL Dd = Dn * Dm 2098 return new FMulD(machInst, rd, rn, rm); 2099 case 0x01: // FDIV Sd = Sn / Sm 2100 return new FDivS(machInst, rd, rn, rm); 2101 case 0x11: // FDIV Dd = Dn / Dm 2102 return new FDivD(machInst, rd, rn, rm); 2103 case 0x02: // FADD Sd = Sn + Sm 2104 return new FAddS(machInst, rd, rn, rm); 2105 case 0x12: // FADD Dd = Dn + Dm 2106 return new FAddD(machInst, rd, rn, rm); 2107 case 0x03: // FSUB Sd = Sn - Sm 2108 return new FSubS(machInst, rd, rn, rm); 2109 case 0x13: // FSUB Dd = Dn - Dm 2110 return new FSubD(machInst, rd, rn, rm); 2111 case 0x04: // FMAX Sd = max(Sn, Sm) 2112 return new FMaxS(machInst, rd, rn, rm); 2113 case 0x14: // FMAX Dd = max(Dn, Dm) 2114 return new FMaxD(machInst, rd, rn, rm); 2115 case 0x05: // FMIN Sd = min(Sn, Sm) 2116 return new FMinS(machInst, rd, rn, rm); 2117 case 0x15: // FMIN Dd = min(Dn, Dm) 2118 return new FMinD(machInst, rd, rn, rm); 2119 case 0x06: // FMAXNM Sd = maxNum(Sn, Sm) 2120 return new FMaxNMS(machInst, rd, rn, rm); 2121 case 0x16: // FMAXNM Dd = maxNum(Dn, Dm) 2122 return new FMaxNMD(machInst, rd, rn, rm); 2123 case 0x07: // FMINNM Sd = minNum(Sn, Sm) 2124 return new FMinNMS(machInst, rd, rn, rm); 2125 case 0x17: // FMINNM Dd = minNum(Dn, Dm) 2126 return new FMinNMD(machInst, rd, rn, rm); 2127 case 0x08: // FNMUL Sd = -(Sn * Sm) 2128 return new FNMulS(machInst, rd, rn, rm); 2129 case 0x18: // FNMUL Dd = -(Dn * Dm) 2130 return new FNMulD(machInst, rd, rn, rm); 2131 default: 2132 return new Unknown64(machInst); 2133 } 2134 } 2135 case 0x3: 2136 { 2137 if (bits(machInst, 31) || bits(machInst, 29)) 2138 return new Unknown64(machInst); 2139 uint8_t type = bits(machInst, 23, 22); 2140 IntRegIndex rd = (IntRegIndex)(uint32_t)bits(machInst, 4, 0); 2141 IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 9, 5); 2142 IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 20, 16); 2143 ConditionCode cond = 2144 (ConditionCode)(uint8_t)(bits(machInst, 15, 12)); 2145 if (type == 0) // FCSEL Sd = if cond then Sn else Sm 2146 return new FCSelS(machInst, rd, rn, rm, cond); 2147 else if (type == 1) // FCSEL Dd = if cond then Dn else Dm 2148 return new FCSelD(machInst, rd, rn, rm, cond); 2149 else 2150 return new Unknown64(machInst); 2151 } 2152 default: 2153 M5_UNREACHABLE; 2154 } 2155 } 2156 M5_UNREACHABLE; 2157 } 2158} 2159}}; 2160 2161output decoder {{ 2162namespace Aarch64 2163{ 2164 StaticInstPtr 2165 decodeAdvSIMDScalar(ExtMachInst machInst) 2166 { 2167 if (bits(machInst, 24) == 1) { 2168 if (bits(machInst, 10) == 0) { 2169 return decodeNeonScIndexedElem(machInst); 2170 } else if (bits(machInst, 23) == 0) { 2171 return decodeNeonScShiftByImm(machInst); 2172 } 2173 } else if (bits(machInst, 21) == 1) { 2174 if (bits(machInst, 10) == 1) { 2175 return decodeNeonSc3Same(machInst); 2176 } else if (bits(machInst, 11) == 0) { 2177 return decodeNeonSc3Diff(machInst); 2178 } else if (bits(machInst, 20, 17) == 0x0) { 2179 return decodeNeonSc2RegMisc(machInst); 2180 } else if (bits(machInst, 20, 17) == 0x4) { 2181 return decodeCryptoTwoRegSHA(machInst); 2182 } else if (bits(machInst, 20, 17) == 0x8) { 2183 return decodeNeonScPwise(machInst); 2184 } else { 2185 return new Unknown64(machInst); 2186 } 2187 } else if (bits(machInst, 23, 22) == 0 && 2188 bits(machInst, 15) == 0) { 2189 if (bits(machInst, 10) == 1) { 2190 return decodeNeonScCopy(machInst); 2191 } else { 2192 return decodeCryptoThreeRegSHA(machInst); 2193 } 2194 } else { 2195 return new Unknown64(machInst); 2196 } 2197 return new FailUnimplemented("Unhandled Case6", machInst); 2198 } 2199} 2200}}; 2201 2202output decoder {{ 2203namespace Aarch64 2204{ 2205 template <typename DecoderFeatures> 2206 StaticInstPtr 2207 decodeFpAdvSIMD(ExtMachInst machInst) 2208 { 2209 2210 if (bits(machInst, 28) == 0) { 2211 if (bits(machInst, 31) == 0) { 2212 return decodeAdvSIMD<DecoderFeatures>(machInst); 2213 } else { 2214 return new Unknown64(machInst); 2215 } 2216 } else if (bits(machInst, 30) == 0) { 2217 return decodeFp(machInst); 2218 } else if (bits(machInst, 31) == 0) { 2219 return decodeAdvSIMDScalar(machInst); 2220 } else { 2221 return new Unknown64(machInst); 2222 } 2223 } 2224} 2225}}; 2226 2227let {{ 2228 decoder_output =''' 2229namespace Aarch64 2230{''' 2231 for decoderFlavour, type_dict in decoders.iteritems(): 2232 decoder_output +=''' 2233template StaticInstPtr decodeFpAdvSIMD<%(df)sDecoder>(ExtMachInst machInst); 2234''' % { "df" : decoderFlavour } 2235 decoder_output +=''' 2236}''' 2237}}; 2238 2239output decoder {{ 2240namespace Aarch64 2241{ 2242 StaticInstPtr 2243 decodeGem5Ops(ExtMachInst machInst) 2244 { 2245 const uint32_t m5func = bits(machInst, 23, 16); 2246 switch (m5func) { 2247 case M5OP_ARM: return new Arm(machInst); 2248 case M5OP_QUIESCE: return new Quiesce(machInst); 2249 case M5OP_QUIESCE_NS: return new QuiesceNs64(machInst); 2250 case M5OP_QUIESCE_CYCLE: return new QuiesceCycles64(machInst); 2251 case M5OP_QUIESCE_TIME: return new QuiesceTime64(machInst); 2252 case M5OP_RPNS: return new Rpns64(machInst); 2253 case M5OP_WAKE_CPU: return new WakeCPU64(machInst); 2254 case M5OP_DEPRECATED1: return new Deprecated_ivlb(machInst); 2255 case M5OP_DEPRECATED2: return new Deprecated_ivle(machInst); 2256 case M5OP_DEPRECATED3: return new Deprecated_exit (machInst); 2257 case M5OP_EXIT: return new M5exit64(machInst); 2258 case M5OP_FAIL: return new M5fail64(machInst); 2259 case M5OP_LOAD_SYMBOL: return new Loadsymbol(machInst); 2260 case M5OP_INIT_PARAM: return new Initparam64(machInst); 2261 case M5OP_RESET_STATS: return new Resetstats64(machInst); 2262 case M5OP_DUMP_STATS: return new Dumpstats64(machInst); 2263 case M5OP_DUMP_RESET_STATS: return new Dumpresetstats64(machInst); 2264 case M5OP_CHECKPOINT: return new M5checkpoint64(machInst); 2265 case M5OP_WRITE_FILE: return new M5writefile64(machInst); 2266 case M5OP_READ_FILE: return new M5readfile64(machInst); 2267 case M5OP_DEBUG_BREAK: return new M5break(machInst); 2268 case M5OP_SWITCH_CPU: return new M5switchcpu(machInst); 2269 case M5OP_ADD_SYMBOL: return new M5addsymbol64(machInst); 2270 case M5OP_PANIC: return new M5panic(machInst); 2271 case M5OP_WORK_BEGIN: return new M5workbegin64(machInst); 2272 case M5OP_WORK_END: return new M5workend64(machInst); 2273 default: return new Unknown64(machInst); 2274 } 2275 } 2276} 2277}}; 2278 2279def format Aarch64() {{ 2280 decode_block = ''' 2281 { 2282 using namespace Aarch64; 2283 if (bits(machInst, 27) == 0x0) { 2284 if (bits(machInst, 28) == 0x0) { 2285 if (bits(machInst, 26, 25) != 0x2) { 2286 return new Unknown64(machInst); 2287 } 2288 if (bits(machInst, 31) == 0x0) { 2289 switch (bits(machInst, 30, 29)) { 2290 case 0x0: 2291 case 0x1: 2292 case 0x2: 2293 return decodeSveInt(machInst); 2294 case 0x3: 2295 return decodeSveFp(machInst); 2296 } 2297 } else { 2298 return decodeSveMem(machInst); 2299 } 2300 } else if (bits(machInst, 26) == 0) 2301 // bit 28:26=100 2302 return decodeDataProcImm(machInst); 2303 else 2304 // bit 28:26=101 2305 return decodeBranchExcSys(machInst); 2306 } else if (bits(machInst, 25) == 0) { 2307 // bit 27=1, 25=0 2308 return decodeLoadsStores(machInst); 2309 } else if (bits(machInst, 26) == 0) { 2310 // bit 27:25=101 2311 return decodeDataProcReg(machInst); 2312 } else if (bits(machInst, 24) == 1 && 2313 bits(machInst, 31, 28) == 0xF) { 2314 return decodeGem5Ops(machInst); 2315 } else { 2316 // bit 27:25=111 2317 switch(decoderFlavour){ 2318 default: 2319 return decodeFpAdvSIMD<GenericDecoder>(machInst); 2320 } 2321 } 2322 } 2323 ''' 2324}};
|