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