426 } 427}}; 428 429def format Thumb32LoadWord() {{ 430 decode = ''' 431 { 432 uint32_t op1 = bits(machInst, 24, 23); 433 if (bits(op1, 1) == 0) { 434 uint32_t op2 = bits(machInst, 11, 6); 435 if (HTRN == 0xF) { 436 if (UP) { 437 return new %(literal_u)s(machInst, RT, INTREG_PC, 438 true, IMMED_11_0); 439 } else { 440 return new %(literal)s(machInst, RT, INTREG_PC, 441 false, IMMED_11_0); 442 } 443 } else if (op1 == 0x1) { 444 return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0); 445 } else if (op2 == 0) { 446 return new %(register)s(machInst, RT, RN, UP, 447 bits(machInst, 5, 4), LSL, RM); 448 } else if ((op2 & 0x3c) == 0x38) { 449 return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0); 450 } else if ((op2 & 0x3c) == 0x30 || //P 451 (op2 & 0x24) == 0x24) { //W 452 uint32_t puw = bits(machInst, 10, 8); 453 uint32_t imm = IMMED_7_0; 454 switch (puw) { 455 case 0: 456 case 2: 457 // If we're here, either P or W must have been set. 458 panic("Neither P or W set, but that " 459 "shouldn't be possible.\\n"); 460 case 1: 461 return new %(imm_w)s(machInst, RT, RN, false, imm); 462 case 3: 463 return new %(imm_uw)s(machInst, RT, RN, true, imm); 464 case 4: 465 return new %(imm_p)s(machInst, RT, RN, false, imm); 466 case 5: 467 return new %(imm_pw)s(machInst, RT, RN, false, imm); 468 case 6: 469 return new %(imm_pu)s(machInst, RT, RN, true, imm); 470 case 7: 471 return new %(imm_puw)s(machInst, RT, RN, true, imm); 472 } 473 } 474 return new Unknown(machInst); 475 } else { 476 return new Unknown(machInst); 477 } 478 } 479 ''' 480 classNames = { 481 "literal_u" : loadImmClassName(False, True, False), 482 "literal" : loadImmClassName(False, False, False), 483 "register" : loadRegClassName(False, True, False), 484 "ldrt" : loadImmClassName(False, True, False, user=True), 485 "imm_w" : loadImmClassName(True, False, True), 486 "imm_uw" : loadImmClassName(True, True, True), 487 "imm_p" : loadImmClassName(False, False, False), 488 "imm_pw" : loadImmClassName(False, False, True), 489 "imm_pu" : loadImmClassName(False, True, False), 490 "imm_puw" : loadImmClassName(False, True, True) 491 } 492 decode_block = decode % classNames 493}}; 494 495def format Thumb32StoreSingle() {{ 496 def buildPuwDecode(size): 497 puwDecode = ''' 498 { 499 uint32_t puw = bits(machInst, 10, 8); 500 uint32_t imm = IMMED_7_0; 501 switch (puw) { 502 case 0: 503 case 2: 504 // If we're here, either P or W must have been set. 505 panic("Neither P or W set, but that " 506 "shouldn't be possible.\\n"); 507 case 1: 508 return new %(imm_w)s(machInst, RT, RN, false, imm); 509 case 3: 510 return new %(imm_uw)s(machInst, RT, RN, true, imm); 511 case 4: 512 return new %(imm_p)s(machInst, RT, RN, false, imm); 513 case 5: 514 return new %(imm_pw)s(machInst, RT, RN, false, imm); 515 case 6: 516 return new %(imm_pu)s(machInst, RT, RN, true, imm); 517 case 7: 518 return new %(imm_puw)s(machInst, RT, RN, true, imm); 519 default: 520 M5_UNREACHABLE; 521 } 522 } 523 ''' 524 return puwDecode % { 525 "imm_w" : storeImmClassName(True, False, True, size=size), 526 "imm_uw" : storeImmClassName(True, True, True, size=size), 527 "imm_p" : storeImmClassName(False, False, False, size=size), 528 "imm_pw" : storeImmClassName(False, False, True, size=size), 529 "imm_pu" : storeImmClassName(False, True, False, size=size), 530 "imm_puw" : storeImmClassName(False, True, True, size=size) 531 } 532 decode = ''' 533 { 534 uint32_t op1 = bits(machInst, 23, 21); 535 uint32_t op2 = bits(machInst, 11, 6); 536 bool op2Puw = ((op2 & 0x24) == 0x24 || 537 (op2 & 0x3c) == 0x30); 538 if (RN == 0xf) { 539 return new Unknown(machInst); 540 } 541 if (op1 == 4) { 542 return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); 543 } else if (op1 == 0 && op2Puw) { 544 %(strb_puw)s; 545 } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { 546 return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); 547 } else if (op1 == 0 && op2 == 0) { 548 return new %(strb_reg)s(machInst, RT, RN, true, 549 bits(machInst, 5, 4), LSL, RM); 550 } else if (op1 == 5) { 551 return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); 552 } else if (op1 == 1 && op2Puw) { 553 %(strh_puw)s; 554 } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { 555 return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); 556 } else if (op1 == 1 && op2 == 0) { 557 return new %(strh_reg)s(machInst, RT, RN, true, 558 bits(machInst, 5, 4), LSL, RM); 559 } else if (op1 == 6) { 560 return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); 561 } else if (op1 == 2 && op2Puw) { 562 %(str_puw)s; 563 } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { 564 return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); 565 } else if (op1 == 2 && op2 == 0) { 566 return new %(str_reg)s(machInst, RT, RN, true, 567 bits(machInst, 5, 4), LSL, RM); 568 } else { 569 return new Unknown(machInst); 570 } 571 } 572 ''' 573 classNames = { 574 "strb_imm" : storeImmClassName(False, True, False, size=1), 575 "strb_puw" : buildPuwDecode(1), 576 "strbt" : storeImmClassName(False, True, False, user=True, size=1), 577 "strb_reg" : storeRegClassName(False, True, False, size=1), 578 "strh_imm" : storeImmClassName(False, True, False, size=2), 579 "strh_puw" : buildPuwDecode(2), 580 "strht" : storeImmClassName(False, True, False, user=True, size=2), 581 "strh_reg" : storeRegClassName(False, True, False, size=2), 582 "str_imm" : storeImmClassName(False, True, False), 583 "str_puw" : buildPuwDecode(4), 584 "strt" : storeImmClassName(False, True, False, user=True), 585 "str_reg" : storeRegClassName(False, True, False) 586 } 587 decode_block = decode % classNames 588}}; 589 590def format LoadByteMemoryHints() {{ 591 decode = ''' 592 { 593 const uint32_t op1 = bits(machInst, 24, 23); 594 const uint32_t op2 = bits(machInst, 11, 6); 595 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 596 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 597 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 598 const uint32_t imm12 = bits(machInst, 11, 0); 599 const uint32_t imm8 = bits(machInst, 7, 0); 600 bool pldw = bits(machInst, 21); 601 const uint32_t imm2 = bits(machInst, 5, 4); 602 if (rn == 0xf) { 603 if (rt == 0xf) { 604 const bool add = bits(machInst, 23); 605 if (bits(op1, 1) == 1) { 606 if (add) { 607 return new %(pli_iulit)s(machInst, INTREG_ZERO, 608 INTREG_PC, true, imm12); 609 } else { 610 return new %(pli_ilit)s(machInst, INTREG_ZERO, 611 INTREG_PC, false, imm12); 612 } 613 } else { 614 if (add) { 615 return new %(pld_iulit)s(machInst, INTREG_ZERO, 616 INTREG_PC, true, imm12); 617 } else { 618 return new %(pld_ilit)s(machInst, INTREG_ZERO, 619 INTREG_PC, false, imm12); 620 } 621 } 622 } else { 623 if (bits(op1, 1) == 1) { 624 if (bits(machInst, 23)) { 625 return new %(ldrsb_lit_u)s(machInst, rt, INTREG_PC, 626 true, imm12); 627 } else { 628 return new %(ldrsb_lit)s(machInst, rt, INTREG_PC, 629 false, imm12); 630 } 631 } else { 632 if (bits(machInst, 23)) { 633 return new %(ldrb_lit_u)s(machInst, rt, INTREG_PC, 634 true, imm12); 635 } else { 636 return new %(ldrb_lit)s(machInst, rt, INTREG_PC, 637 false, imm12); 638 } 639 } 640 } 641 } else if (rt == 0xf) { 642 switch (op1) { 643 case 0x0: 644 if (op2 == 0x0) { 645 if (pldw) { 646 return new %(pldw_radd)s(machInst, INTREG_ZERO, 647 rn, true, imm2, LSL, rm); 648 } else { 649 return new %(pld_radd)s(machInst, INTREG_ZERO, 650 rn, true, imm2, LSL, rm); 651 } 652 } else if (bits(op2, 5, 2) == 0xc) { 653 if (pldw) { 654 return new %(pldw_isub)s(machInst, INTREG_ZERO, 655 rn, false, imm8); 656 } else { 657 return new %(pld_isub)s(machInst, INTREG_ZERO, 658 rn, false, imm8); 659 } 660 } 661 break; 662 case 0x1: 663 if (pldw) { 664 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 665 rn, true, imm12); 666 } else { 667 return new %(pld_iadd)s(machInst, INTREG_ZERO, 668 rn, true, imm12); 669 } 670 case 0x2: 671 if (op2 == 0x0) { 672 return new %(pli_radd)s(machInst, INTREG_ZERO, rn, 673 true, imm2, LSL, rm); 674 } else if (bits(op2, 5, 2) == 0xc) { 675 return new %(pli_ilit)s(machInst, INTREG_ZERO, 676 INTREG_PC, false, imm8); 677 } 678 break; 679 case 0x3: 680 return new %(pli_iulit)s(machInst, INTREG_ZERO, 681 INTREG_PC, true, imm12); 682 } 683 return new Unknown(machInst); 684 } else { 685 switch (op1) { 686 case 0x0: 687 if (op2 == 0) { 688 return new %(ldrb_radd)s(machInst, rt, rn, true, 689 imm2, LSL, rm); 690 } else if (bits(op2, 5, 2) == 0xe) { 691 return new %(ldrbt)s(machInst, rt, rn, true, imm8); 692 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 693 const uint32_t puw = bits(machInst, 10, 8); 694 switch (puw) { 695 case 0x1: 696 return new %(ldrb_iw)s(machInst, rt, 697 rn, false, imm8); 698 case 0x3: 699 return new %(ldrb_iuw)s(machInst, rt, 700 rn, true, imm8); 701 case 0x4: 702 return new %(ldrb_ip)s(machInst, rt, 703 rn, false, imm8); 704 case 0x5: 705 return new %(ldrb_ipw)s(machInst, rt, 706 rn, false, imm8); 707 case 0x7: 708 return new %(ldrb_ipuw)s(machInst, rt, 709 rn, true, imm8); 710 } 711 } 712 break; 713 case 0x1: 714 return new %(ldrb_iadd)s(machInst, rt, rn, true, imm12); 715 case 0x2: 716 if (op2 == 0) { 717 return new %(ldrsb_radd)s(machInst, rt, rn, true, 718 imm2, LSL, rm); 719 } else if (bits(op2, 5, 2) == 0xe) { 720 return new %(ldrsbt)s(machInst, rt, rn, true, imm8); 721 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 722 const uint32_t puw = bits(machInst, 10, 8); 723 switch (puw) { 724 case 0x1: 725 return new %(ldrsb_iw)s(machInst, rt, 726 rn, false, imm8); 727 case 0x3: 728 return new %(ldrsb_iuw)s(machInst, rt, 729 rn, true, imm8); 730 case 0x4: 731 return new %(ldrsb_ip)s(machInst, rt, 732 rn, false, imm8); 733 case 0x5: 734 return new %(ldrsb_ipw)s(machInst, rt, 735 rn, false, imm8); 736 case 0x7: 737 return new %(ldrsb_ipuw)s(machInst, rt, 738 rn, true, imm8); 739 } 740 } 741 break; 742 case 0x3: 743 return new %(ldrsb_iadd)s(machInst, rt, rn, true, imm12); 744 } 745 return new Unknown(machInst); 746 } 747 } 748 ''' 749 substDict = { 750 "ldrsb_lit_u" : loadImmClassName(False, True, False, 1, True), 751 "ldrsb_lit" : loadImmClassName(False, False, False, 1, True), 752 "ldrb_lit_u" : loadImmClassName(False, True, False, 1), 753 "ldrb_lit" : loadImmClassName(False, False, False, 1), 754 "ldrsb_radd" : loadRegClassName(False, True, False, 1, True), 755 "ldrb_radd" : loadRegClassName(False, True, False, 1), 756 "ldrsb_iw" : loadImmClassName(True, False, True, 1, True), 757 "ldrsb_iuw" : loadImmClassName(True, True, True, 1, True), 758 "ldrsb_ip" : loadImmClassName(False, False, False, 1, True), 759 "ldrsb_ipw" : loadImmClassName(False, False, True, 1, True), 760 "ldrsb_ipuw" : loadImmClassName(False, True, True, 1, True), 761 "ldrsb_iadd" : loadImmClassName(False, True, False, 1, True), 762 "ldrb_iw" : loadImmClassName(True, False, True, 1), 763 "ldrb_iuw" : loadImmClassName(True, True, True, 1), 764 "ldrb_ip" : loadImmClassName(False, False, False, 1), 765 "ldrb_ipw" : loadImmClassName(False, False, True, 1), 766 "ldrb_ipuw" : loadImmClassName(False, True, True, 1), 767 "ldrb_iadd" : loadImmClassName(False, True, False, 1), 768 "ldrbt" : loadImmClassName(False, True, False, 1, user=True), 769 "ldrsbt" : loadImmClassName(False, True, False, 1, True, user=True), 770 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 771 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 772 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 773 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 774 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 775 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1), 776 "pld_iulit" : "PLD_" + loadImmClassName(False, True, False, 1), 777 "pld_ilit" : "PLD_" + loadImmClassName(False, False, False, 1), 778 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 779 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1), 780 "pli_radd" : "PLI_" + loadRegClassName(False, True, False, 1), 781 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 782 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1) 783 } 784 decode_block = decode % substDict 785}}; 786 787def format LoadHalfwordMemoryHints() {{ 788 decode = ''' 789 { 790 const uint32_t op1 = bits(machInst, 24, 23); 791 const uint32_t op2 = bits(machInst, 11, 6); 792 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 793 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 794 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 795 const uint32_t imm12 = bits(machInst, 11, 0); 796 const uint32_t imm8 = bits(machInst, 7, 0); 797 bool pldw = bits(machInst, 21); 798 const uint32_t imm2 = bits(machInst, 5, 4); 799 if (rn == 0xf) { 800 if (rt == 0xf) { 801 if (bits(op1, 1) == 1) { 802 // Unallocated memory hint 803 return new NopInst(machInst); 804 } else { 805 return new Unknown(machInst); 806 } 807 } else { 808 if (bits(op1, 1) == 1) { 809 if (bits(machInst, 23)) { 810 return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC, 811 true, imm12); 812 } else { 813 return new %(ldrsh_lit)s(machInst, rt, INTREG_PC, 814 false, imm12); 815 } 816 } else { 817 if (bits(machInst, 23)) { 818 return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC, 819 true, imm12); 820 } else { 821 return new %(ldrh_lit)s(machInst, rt, INTREG_PC, 822 false, imm12); 823 } 824 } 825 } 826 } else if (rt == 0xf) { 827 switch (op1) { 828 case 0x0: 829 if (op2 == 0x0) { 830 if (pldw) { 831 return new %(pldw_radd)s(machInst, INTREG_ZERO, 832 rn, true, imm2, LSL, rm); 833 } else { 834 return new %(pld_radd)s(machInst, INTREG_ZERO, 835 rn, true, imm2, LSL, rm); 836 } 837 } else if (bits(op2, 5, 2) == 0xc) { 838 if (pldw) { 839 return new %(pldw_isub)s(machInst, INTREG_ZERO, 840 rn, false, imm8); 841 } else { 842 return new %(pld_isub)s(machInst, INTREG_ZERO, 843 rn, false, imm8); 844 } 845 } 846 break; 847 case 0x1: 848 if (pldw) { 849 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 850 rn, true, imm12); 851 } else { 852 return new %(pld_iadd)s(machInst, INTREG_ZERO, 853 rn, true, imm12); 854 } 855 case 0x2: 856 if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) { 857 // Unallocated memory hint 858 return new NopInst(machInst); 859 } 860 break; 861 case 0x3: 862 return new NopInst(machInst); 863 } 864 return new Unknown(machInst); 865 } else { 866 switch (op1) { 867 case 0x0: 868 if (op2 == 0) { 869 return new %(ldrh_radd)s(machInst, rt, rn, true, 870 imm2, LSL, rm); 871 } else if (bits(op2, 5, 2) == 0xe) { 872 return new %(ldrht)s(machInst, rt, rn, true, imm8); 873 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 874 const uint32_t puw = bits(machInst, 10, 8); 875 switch (puw) { 876 case 0x1: 877 return new %(ldrh_iw)s(machInst, rt, 878 rn, false, imm8); 879 case 0x3: 880 return new %(ldrh_iuw)s(machInst, rt, 881 rn, true, imm8); 882 case 0x4: 883 return new %(ldrh_ip)s(machInst, rt, 884 rn, false, imm8); 885 case 0x5: 886 return new %(ldrh_ipw)s(machInst, rt, 887 rn, false, imm8); 888 case 0x7: 889 return new %(ldrh_ipuw)s(machInst, rt, 890 rn, true, imm8); 891 } 892 } 893 break; 894 case 0x1: 895 return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12); 896 case 0x2: 897 if (op2 == 0) { 898 return new %(ldrsh_radd)s(machInst, rt, rn, true, 899 imm2, LSL, rm); 900 } else if (bits(op2, 5, 2) == 0xe) { 901 return new %(ldrsht)s(machInst, rt, rn, true, imm8); 902 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 903 const uint32_t puw = bits(machInst, 10, 8); 904 switch (puw) { 905 case 0x1: 906 return new %(ldrsh_iw)s(machInst, rt, 907 rn, false, imm8); 908 case 0x3: 909 return new %(ldrsh_iuw)s(machInst, rt, 910 rn, true, imm8); 911 case 0x4: 912 return new %(ldrsh_ip)s(machInst, rt, 913 rn, false, imm8); 914 case 0x5: 915 return new %(ldrsh_ipw)s(machInst, rt, 916 rn, false, imm8); 917 case 0x7: 918 return new %(ldrsh_ipuw)s(machInst, rt, 919 rn, true, imm8); 920 } 921 } 922 break; 923 case 0x3: 924 return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12); 925 } 926 return new Unknown(machInst); 927 } 928 } 929 ''' 930 substDict = { 931 "ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True), 932 "ldrsh_lit" : loadImmClassName(False, False, False, 2, True), 933 "ldrh_lit_u" : loadImmClassName(False, True, False, 2), 934 "ldrh_lit" : loadImmClassName(False, False, False, 2), 935 "ldrsh_radd" : loadRegClassName(False, True, False, 2, True), 936 "ldrh_radd" : loadRegClassName(False, True, False, 2), 937 "ldrsh_iw" : loadImmClassName(True, False, True, 2, True), 938 "ldrsh_iuw" : loadImmClassName(True, True, True, 2, True), 939 "ldrsh_ip" : loadImmClassName(False, False, False, 2, True), 940 "ldrsh_ipw" : loadImmClassName(False, False, True, 2, True), 941 "ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True), 942 "ldrsh_iadd" : loadImmClassName(False, True, False, 2, True), 943 "ldrh_iw" : loadImmClassName(True, False, True, 2), 944 "ldrh_iuw" : loadImmClassName(True, True, True, 2), 945 "ldrh_ip" : loadImmClassName(False, False, False, 2), 946 "ldrh_ipw" : loadImmClassName(False, False, True, 2), 947 "ldrh_ipuw" : loadImmClassName(False, True, True, 2), 948 "ldrh_iadd" : loadImmClassName(False, True, False, 2), 949 "ldrht" : loadImmClassName(False, True, False, 2, user=True), 950 "ldrsht" : loadImmClassName(False, True, False, 2, True, user=True), 951 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 952 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 953 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 954 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 955 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 956 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1) 957 } 958 decode_block = decode % substDict 959}}; 960 961def format Thumb16MemReg() {{ 962 decode = ''' 963 { 964 const uint32_t opb = bits(machInst, 11, 9); 965 const uint32_t rt = bits(machInst, 2, 0); 966 const uint32_t rn = bits(machInst, 5, 3); 967 const uint32_t rm = bits(machInst, 8, 6); 968 switch (opb) { 969 case 0x0: 970 return new %(str)s(machInst, rt, rn, true, 0, LSL, rm); 971 case 0x1: 972 return new %(strh)s(machInst, rt, rn, true, 0, LSL, rm); 973 case 0x2: 974 return new %(strb)s(machInst, rt, rn, true, 0, LSL, rm); 975 case 0x3: 976 return new %(ldrsb)s(machInst, rt, rn, true, 0, LSL, rm); 977 case 0x4: 978 return new %(ldr)s(machInst, rt, rn, true, 0, LSL, rm); 979 case 0x5: 980 return new %(ldrh)s(machInst, rt, rn, true, 0, LSL, rm); 981 case 0x6: 982 return new %(ldrb)s(machInst, rt, rn, true, 0, LSL, rm); 983 case 0x7: 984 return new %(ldrsh)s(machInst, rt, rn, true, 0, LSL, rm); 985 default: 986 M5_UNREACHABLE; 987 } 988 } 989 ''' 990 classNames = { 991 "str" : storeRegClassName(False, True, False), 992 "strh" : storeRegClassName(False, True, False, size=2), 993 "strb" : storeRegClassName(False, True, False, size=1), 994 "ldrsb" : loadRegClassName(False, True, False, sign=True, size=1), 995 "ldr" : loadRegClassName(False, True, False), 996 "ldrh" : loadRegClassName(False, True, False, size=2), 997 "ldrb" : loadRegClassName(False, True, False, size=1), 998 "ldrsh" : loadRegClassName(False, True, False, sign=True, size=2), 999 } 1000 decode_block = decode % classNames 1001}}; 1002 1003def format Thumb16MemImm() {{ 1004 decode = ''' 1005 { 1006 const uint32_t opa = bits(machInst, 15, 12); 1007 const uint32_t opb = bits(machInst, 11, 9); 1008 const uint32_t lrt = bits(machInst, 2, 0); 1009 const uint32_t lrn = bits(machInst, 5, 3); 1010 const uint32_t hrt = bits(machInst, 10, 8); 1011 const uint32_t imm5 = bits(machInst, 10, 6); 1012 const uint32_t imm8 = bits(machInst, 7, 0); 1013 const bool load = bits(opb, 2); 1014 switch (opa) { 1015 case 0x6: 1016 if (load) { 1017 return new %(ldr)s(machInst, lrt, lrn, true, imm5 << 2); 1018 } else { 1019 return new %(str)s(machInst, lrt, lrn, true, imm5 << 2); 1020 } 1021 case 0x7: 1022 if (load) { 1023 return new %(ldrb)s(machInst, lrt, lrn, true, imm5); 1024 } else { 1025 return new %(strb)s(machInst, lrt, lrn, true, imm5); 1026 } 1027 case 0x8: 1028 if (load) { 1029 return new %(ldrh)s(machInst, lrt, lrn, true, imm5 << 1); 1030 } else { 1031 return new %(strh)s(machInst, lrt, lrn, true, imm5 << 1); 1032 } 1033 case 0x9: 1034 if (load) { 1035 return new %(ldr)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 1036 } else { 1037 return new %(str)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 1038 } 1039 default: 1040 return new Unknown(machInst); 1041 } 1042 } 1043 ''' 1044 classNames = { 1045 "ldr" : loadImmClassName(False, True, False), 1046 "str" : storeImmClassName(False, True, False), 1047 "ldrh" : loadImmClassName(False, True, False, size=2), 1048 "strh" : storeImmClassName(False, True, False, size=2), 1049 "ldrb" : loadImmClassName(False, True, False, size=1), 1050 "strb" : storeImmClassName(False, True, False, size=1), 1051 } 1052 decode_block = decode % classNames 1053}}; 1054 1055def format Thumb16MemLit() {{ 1056 decode_block = ''' 1057 { 1058 const uint32_t rt = bits(machInst, 10, 8); 1059 const uint32_t imm8 = bits(machInst, 7, 0); 1060 return new %s(machInst, rt, INTREG_PC, true, imm8 << 2); 1061 } 1062 ''' % loadImmClassName(False, True, False) 1063}}; 1064
| 519 } 520}}; 521 522def format Thumb32LoadWord() {{ 523 decode = ''' 524 { 525 uint32_t op1 = bits(machInst, 24, 23); 526 if (bits(op1, 1) == 0) { 527 uint32_t op2 = bits(machInst, 11, 6); 528 if (HTRN == 0xF) { 529 if (UP) { 530 return new %(literal_u)s(machInst, RT, INTREG_PC, 531 true, IMMED_11_0); 532 } else { 533 return new %(literal)s(machInst, RT, INTREG_PC, 534 false, IMMED_11_0); 535 } 536 } else if (op1 == 0x1) { 537 return new %(imm_pu)s(machInst, RT, RN, true, IMMED_11_0); 538 } else if (op2 == 0) { 539 return new %(register)s(machInst, RT, RN, UP, 540 bits(machInst, 5, 4), LSL, RM); 541 } else if ((op2 & 0x3c) == 0x38) { 542 return new %(ldrt)s(machInst, RT, RN, true, IMMED_7_0); 543 } else if ((op2 & 0x3c) == 0x30 || //P 544 (op2 & 0x24) == 0x24) { //W 545 uint32_t puw = bits(machInst, 10, 8); 546 uint32_t imm = IMMED_7_0; 547 switch (puw) { 548 case 0: 549 case 2: 550 // If we're here, either P or W must have been set. 551 panic("Neither P or W set, but that " 552 "shouldn't be possible.\\n"); 553 case 1: 554 return new %(imm_w)s(machInst, RT, RN, false, imm); 555 case 3: 556 return new %(imm_uw)s(machInst, RT, RN, true, imm); 557 case 4: 558 return new %(imm_p)s(machInst, RT, RN, false, imm); 559 case 5: 560 return new %(imm_pw)s(machInst, RT, RN, false, imm); 561 case 6: 562 return new %(imm_pu)s(machInst, RT, RN, true, imm); 563 case 7: 564 return new %(imm_puw)s(machInst, RT, RN, true, imm); 565 } 566 } 567 return new Unknown(machInst); 568 } else { 569 return new Unknown(machInst); 570 } 571 } 572 ''' 573 classNames = { 574 "literal_u" : loadImmClassName(False, True, False), 575 "literal" : loadImmClassName(False, False, False), 576 "register" : loadRegClassName(False, True, False), 577 "ldrt" : loadImmClassName(False, True, False, user=True), 578 "imm_w" : loadImmClassName(True, False, True), 579 "imm_uw" : loadImmClassName(True, True, True), 580 "imm_p" : loadImmClassName(False, False, False), 581 "imm_pw" : loadImmClassName(False, False, True), 582 "imm_pu" : loadImmClassName(False, True, False), 583 "imm_puw" : loadImmClassName(False, True, True) 584 } 585 decode_block = decode % classNames 586}}; 587 588def format Thumb32StoreSingle() {{ 589 def buildPuwDecode(size): 590 puwDecode = ''' 591 { 592 uint32_t puw = bits(machInst, 10, 8); 593 uint32_t imm = IMMED_7_0; 594 switch (puw) { 595 case 0: 596 case 2: 597 // If we're here, either P or W must have been set. 598 panic("Neither P or W set, but that " 599 "shouldn't be possible.\\n"); 600 case 1: 601 return new %(imm_w)s(machInst, RT, RN, false, imm); 602 case 3: 603 return new %(imm_uw)s(machInst, RT, RN, true, imm); 604 case 4: 605 return new %(imm_p)s(machInst, RT, RN, false, imm); 606 case 5: 607 return new %(imm_pw)s(machInst, RT, RN, false, imm); 608 case 6: 609 return new %(imm_pu)s(machInst, RT, RN, true, imm); 610 case 7: 611 return new %(imm_puw)s(machInst, RT, RN, true, imm); 612 default: 613 M5_UNREACHABLE; 614 } 615 } 616 ''' 617 return puwDecode % { 618 "imm_w" : storeImmClassName(True, False, True, size=size), 619 "imm_uw" : storeImmClassName(True, True, True, size=size), 620 "imm_p" : storeImmClassName(False, False, False, size=size), 621 "imm_pw" : storeImmClassName(False, False, True, size=size), 622 "imm_pu" : storeImmClassName(False, True, False, size=size), 623 "imm_puw" : storeImmClassName(False, True, True, size=size) 624 } 625 decode = ''' 626 { 627 uint32_t op1 = bits(machInst, 23, 21); 628 uint32_t op2 = bits(machInst, 11, 6); 629 bool op2Puw = ((op2 & 0x24) == 0x24 || 630 (op2 & 0x3c) == 0x30); 631 if (RN == 0xf) { 632 return new Unknown(machInst); 633 } 634 if (op1 == 4) { 635 return new %(strb_imm)s(machInst, RT, RN, true, IMMED_11_0); 636 } else if (op1 == 0 && op2Puw) { 637 %(strb_puw)s; 638 } else if (op1 == 0 && ((op2 & 0x3c) == 0x38)) { 639 return new %(strbt)s(machInst, RT, RN, true, IMMED_7_0); 640 } else if (op1 == 0 && op2 == 0) { 641 return new %(strb_reg)s(machInst, RT, RN, true, 642 bits(machInst, 5, 4), LSL, RM); 643 } else if (op1 == 5) { 644 return new %(strh_imm)s(machInst, RT, RN, true, IMMED_11_0); 645 } else if (op1 == 1 && op2Puw) { 646 %(strh_puw)s; 647 } else if (op1 == 1 && ((op2 & 0x3c) == 0x38)) { 648 return new %(strht)s(machInst, RT, RN, true, IMMED_7_0); 649 } else if (op1 == 1 && op2 == 0) { 650 return new %(strh_reg)s(machInst, RT, RN, true, 651 bits(machInst, 5, 4), LSL, RM); 652 } else if (op1 == 6) { 653 return new %(str_imm)s(machInst, RT, RN, true, IMMED_11_0); 654 } else if (op1 == 2 && op2Puw) { 655 %(str_puw)s; 656 } else if (op1 == 2 && ((op2 & 0x3c) == 0x38)) { 657 return new %(strt)s(machInst, RT, RN, true, IMMED_7_0); 658 } else if (op1 == 2 && op2 == 0) { 659 return new %(str_reg)s(machInst, RT, RN, true, 660 bits(machInst, 5, 4), LSL, RM); 661 } else { 662 return new Unknown(machInst); 663 } 664 } 665 ''' 666 classNames = { 667 "strb_imm" : storeImmClassName(False, True, False, size=1), 668 "strb_puw" : buildPuwDecode(1), 669 "strbt" : storeImmClassName(False, True, False, user=True, size=1), 670 "strb_reg" : storeRegClassName(False, True, False, size=1), 671 "strh_imm" : storeImmClassName(False, True, False, size=2), 672 "strh_puw" : buildPuwDecode(2), 673 "strht" : storeImmClassName(False, True, False, user=True, size=2), 674 "strh_reg" : storeRegClassName(False, True, False, size=2), 675 "str_imm" : storeImmClassName(False, True, False), 676 "str_puw" : buildPuwDecode(4), 677 "strt" : storeImmClassName(False, True, False, user=True), 678 "str_reg" : storeRegClassName(False, True, False) 679 } 680 decode_block = decode % classNames 681}}; 682 683def format LoadByteMemoryHints() {{ 684 decode = ''' 685 { 686 const uint32_t op1 = bits(machInst, 24, 23); 687 const uint32_t op2 = bits(machInst, 11, 6); 688 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 689 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 690 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 691 const uint32_t imm12 = bits(machInst, 11, 0); 692 const uint32_t imm8 = bits(machInst, 7, 0); 693 bool pldw = bits(machInst, 21); 694 const uint32_t imm2 = bits(machInst, 5, 4); 695 if (rn == 0xf) { 696 if (rt == 0xf) { 697 const bool add = bits(machInst, 23); 698 if (bits(op1, 1) == 1) { 699 if (add) { 700 return new %(pli_iulit)s(machInst, INTREG_ZERO, 701 INTREG_PC, true, imm12); 702 } else { 703 return new %(pli_ilit)s(machInst, INTREG_ZERO, 704 INTREG_PC, false, imm12); 705 } 706 } else { 707 if (add) { 708 return new %(pld_iulit)s(machInst, INTREG_ZERO, 709 INTREG_PC, true, imm12); 710 } else { 711 return new %(pld_ilit)s(machInst, INTREG_ZERO, 712 INTREG_PC, false, imm12); 713 } 714 } 715 } else { 716 if (bits(op1, 1) == 1) { 717 if (bits(machInst, 23)) { 718 return new %(ldrsb_lit_u)s(machInst, rt, INTREG_PC, 719 true, imm12); 720 } else { 721 return new %(ldrsb_lit)s(machInst, rt, INTREG_PC, 722 false, imm12); 723 } 724 } else { 725 if (bits(machInst, 23)) { 726 return new %(ldrb_lit_u)s(machInst, rt, INTREG_PC, 727 true, imm12); 728 } else { 729 return new %(ldrb_lit)s(machInst, rt, INTREG_PC, 730 false, imm12); 731 } 732 } 733 } 734 } else if (rt == 0xf) { 735 switch (op1) { 736 case 0x0: 737 if (op2 == 0x0) { 738 if (pldw) { 739 return new %(pldw_radd)s(machInst, INTREG_ZERO, 740 rn, true, imm2, LSL, rm); 741 } else { 742 return new %(pld_radd)s(machInst, INTREG_ZERO, 743 rn, true, imm2, LSL, rm); 744 } 745 } else if (bits(op2, 5, 2) == 0xc) { 746 if (pldw) { 747 return new %(pldw_isub)s(machInst, INTREG_ZERO, 748 rn, false, imm8); 749 } else { 750 return new %(pld_isub)s(machInst, INTREG_ZERO, 751 rn, false, imm8); 752 } 753 } 754 break; 755 case 0x1: 756 if (pldw) { 757 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 758 rn, true, imm12); 759 } else { 760 return new %(pld_iadd)s(machInst, INTREG_ZERO, 761 rn, true, imm12); 762 } 763 case 0x2: 764 if (op2 == 0x0) { 765 return new %(pli_radd)s(machInst, INTREG_ZERO, rn, 766 true, imm2, LSL, rm); 767 } else if (bits(op2, 5, 2) == 0xc) { 768 return new %(pli_ilit)s(machInst, INTREG_ZERO, 769 INTREG_PC, false, imm8); 770 } 771 break; 772 case 0x3: 773 return new %(pli_iulit)s(machInst, INTREG_ZERO, 774 INTREG_PC, true, imm12); 775 } 776 return new Unknown(machInst); 777 } else { 778 switch (op1) { 779 case 0x0: 780 if (op2 == 0) { 781 return new %(ldrb_radd)s(machInst, rt, rn, true, 782 imm2, LSL, rm); 783 } else if (bits(op2, 5, 2) == 0xe) { 784 return new %(ldrbt)s(machInst, rt, rn, true, imm8); 785 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 786 const uint32_t puw = bits(machInst, 10, 8); 787 switch (puw) { 788 case 0x1: 789 return new %(ldrb_iw)s(machInst, rt, 790 rn, false, imm8); 791 case 0x3: 792 return new %(ldrb_iuw)s(machInst, rt, 793 rn, true, imm8); 794 case 0x4: 795 return new %(ldrb_ip)s(machInst, rt, 796 rn, false, imm8); 797 case 0x5: 798 return new %(ldrb_ipw)s(machInst, rt, 799 rn, false, imm8); 800 case 0x7: 801 return new %(ldrb_ipuw)s(machInst, rt, 802 rn, true, imm8); 803 } 804 } 805 break; 806 case 0x1: 807 return new %(ldrb_iadd)s(machInst, rt, rn, true, imm12); 808 case 0x2: 809 if (op2 == 0) { 810 return new %(ldrsb_radd)s(machInst, rt, rn, true, 811 imm2, LSL, rm); 812 } else if (bits(op2, 5, 2) == 0xe) { 813 return new %(ldrsbt)s(machInst, rt, rn, true, imm8); 814 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 815 const uint32_t puw = bits(machInst, 10, 8); 816 switch (puw) { 817 case 0x1: 818 return new %(ldrsb_iw)s(machInst, rt, 819 rn, false, imm8); 820 case 0x3: 821 return new %(ldrsb_iuw)s(machInst, rt, 822 rn, true, imm8); 823 case 0x4: 824 return new %(ldrsb_ip)s(machInst, rt, 825 rn, false, imm8); 826 case 0x5: 827 return new %(ldrsb_ipw)s(machInst, rt, 828 rn, false, imm8); 829 case 0x7: 830 return new %(ldrsb_ipuw)s(machInst, rt, 831 rn, true, imm8); 832 } 833 } 834 break; 835 case 0x3: 836 return new %(ldrsb_iadd)s(machInst, rt, rn, true, imm12); 837 } 838 return new Unknown(machInst); 839 } 840 } 841 ''' 842 substDict = { 843 "ldrsb_lit_u" : loadImmClassName(False, True, False, 1, True), 844 "ldrsb_lit" : loadImmClassName(False, False, False, 1, True), 845 "ldrb_lit_u" : loadImmClassName(False, True, False, 1), 846 "ldrb_lit" : loadImmClassName(False, False, False, 1), 847 "ldrsb_radd" : loadRegClassName(False, True, False, 1, True), 848 "ldrb_radd" : loadRegClassName(False, True, False, 1), 849 "ldrsb_iw" : loadImmClassName(True, False, True, 1, True), 850 "ldrsb_iuw" : loadImmClassName(True, True, True, 1, True), 851 "ldrsb_ip" : loadImmClassName(False, False, False, 1, True), 852 "ldrsb_ipw" : loadImmClassName(False, False, True, 1, True), 853 "ldrsb_ipuw" : loadImmClassName(False, True, True, 1, True), 854 "ldrsb_iadd" : loadImmClassName(False, True, False, 1, True), 855 "ldrb_iw" : loadImmClassName(True, False, True, 1), 856 "ldrb_iuw" : loadImmClassName(True, True, True, 1), 857 "ldrb_ip" : loadImmClassName(False, False, False, 1), 858 "ldrb_ipw" : loadImmClassName(False, False, True, 1), 859 "ldrb_ipuw" : loadImmClassName(False, True, True, 1), 860 "ldrb_iadd" : loadImmClassName(False, True, False, 1), 861 "ldrbt" : loadImmClassName(False, True, False, 1, user=True), 862 "ldrsbt" : loadImmClassName(False, True, False, 1, True, user=True), 863 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 864 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 865 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 866 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 867 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 868 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1), 869 "pld_iulit" : "PLD_" + loadImmClassName(False, True, False, 1), 870 "pld_ilit" : "PLD_" + loadImmClassName(False, False, False, 1), 871 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 872 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1), 873 "pli_radd" : "PLI_" + loadRegClassName(False, True, False, 1), 874 "pli_iulit" : "PLI_" + loadImmClassName(False, True, False, 1), 875 "pli_ilit" : "PLI_" + loadImmClassName(False, False, False, 1) 876 } 877 decode_block = decode % substDict 878}}; 879 880def format LoadHalfwordMemoryHints() {{ 881 decode = ''' 882 { 883 const uint32_t op1 = bits(machInst, 24, 23); 884 const uint32_t op2 = bits(machInst, 11, 6); 885 const IntRegIndex rn = (IntRegIndex)(uint32_t)bits(machInst, 19, 16); 886 const IntRegIndex rt = (IntRegIndex)(uint32_t)bits(machInst, 15, 12); 887 const IntRegIndex rm = (IntRegIndex)(uint32_t)bits(machInst, 3, 0); 888 const uint32_t imm12 = bits(machInst, 11, 0); 889 const uint32_t imm8 = bits(machInst, 7, 0); 890 bool pldw = bits(machInst, 21); 891 const uint32_t imm2 = bits(machInst, 5, 4); 892 if (rn == 0xf) { 893 if (rt == 0xf) { 894 if (bits(op1, 1) == 1) { 895 // Unallocated memory hint 896 return new NopInst(machInst); 897 } else { 898 return new Unknown(machInst); 899 } 900 } else { 901 if (bits(op1, 1) == 1) { 902 if (bits(machInst, 23)) { 903 return new %(ldrsh_lit_u)s(machInst, rt, INTREG_PC, 904 true, imm12); 905 } else { 906 return new %(ldrsh_lit)s(machInst, rt, INTREG_PC, 907 false, imm12); 908 } 909 } else { 910 if (bits(machInst, 23)) { 911 return new %(ldrh_lit_u)s(machInst, rt, INTREG_PC, 912 true, imm12); 913 } else { 914 return new %(ldrh_lit)s(machInst, rt, INTREG_PC, 915 false, imm12); 916 } 917 } 918 } 919 } else if (rt == 0xf) { 920 switch (op1) { 921 case 0x0: 922 if (op2 == 0x0) { 923 if (pldw) { 924 return new %(pldw_radd)s(machInst, INTREG_ZERO, 925 rn, true, imm2, LSL, rm); 926 } else { 927 return new %(pld_radd)s(machInst, INTREG_ZERO, 928 rn, true, imm2, LSL, rm); 929 } 930 } else if (bits(op2, 5, 2) == 0xc) { 931 if (pldw) { 932 return new %(pldw_isub)s(machInst, INTREG_ZERO, 933 rn, false, imm8); 934 } else { 935 return new %(pld_isub)s(machInst, INTREG_ZERO, 936 rn, false, imm8); 937 } 938 } 939 break; 940 case 0x1: 941 if (pldw) { 942 return new %(pldw_iadd)s(machInst, INTREG_ZERO, 943 rn, true, imm12); 944 } else { 945 return new %(pld_iadd)s(machInst, INTREG_ZERO, 946 rn, true, imm12); 947 } 948 case 0x2: 949 if (op2 == 0x0 || bits(op2, 5, 2) == 0xc) { 950 // Unallocated memory hint 951 return new NopInst(machInst); 952 } 953 break; 954 case 0x3: 955 return new NopInst(machInst); 956 } 957 return new Unknown(machInst); 958 } else { 959 switch (op1) { 960 case 0x0: 961 if (op2 == 0) { 962 return new %(ldrh_radd)s(machInst, rt, rn, true, 963 imm2, LSL, rm); 964 } else if (bits(op2, 5, 2) == 0xe) { 965 return new %(ldrht)s(machInst, rt, rn, true, imm8); 966 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 967 const uint32_t puw = bits(machInst, 10, 8); 968 switch (puw) { 969 case 0x1: 970 return new %(ldrh_iw)s(machInst, rt, 971 rn, false, imm8); 972 case 0x3: 973 return new %(ldrh_iuw)s(machInst, rt, 974 rn, true, imm8); 975 case 0x4: 976 return new %(ldrh_ip)s(machInst, rt, 977 rn, false, imm8); 978 case 0x5: 979 return new %(ldrh_ipw)s(machInst, rt, 980 rn, false, imm8); 981 case 0x7: 982 return new %(ldrh_ipuw)s(machInst, rt, 983 rn, true, imm8); 984 } 985 } 986 break; 987 case 0x1: 988 return new %(ldrh_iadd)s(machInst, rt, rn, true, imm12); 989 case 0x2: 990 if (op2 == 0) { 991 return new %(ldrsh_radd)s(machInst, rt, rn, true, 992 imm2, LSL, rm); 993 } else if (bits(op2, 5, 2) == 0xe) { 994 return new %(ldrsht)s(machInst, rt, rn, true, imm8); 995 } else if ((op2 & 0x24) == 0x24 || bits(op2, 5, 2) == 0xc) { 996 const uint32_t puw = bits(machInst, 10, 8); 997 switch (puw) { 998 case 0x1: 999 return new %(ldrsh_iw)s(machInst, rt, 1000 rn, false, imm8); 1001 case 0x3: 1002 return new %(ldrsh_iuw)s(machInst, rt, 1003 rn, true, imm8); 1004 case 0x4: 1005 return new %(ldrsh_ip)s(machInst, rt, 1006 rn, false, imm8); 1007 case 0x5: 1008 return new %(ldrsh_ipw)s(machInst, rt, 1009 rn, false, imm8); 1010 case 0x7: 1011 return new %(ldrsh_ipuw)s(machInst, rt, 1012 rn, true, imm8); 1013 } 1014 } 1015 break; 1016 case 0x3: 1017 return new %(ldrsh_iadd)s(machInst, rt, rn, true, imm12); 1018 } 1019 return new Unknown(machInst); 1020 } 1021 } 1022 ''' 1023 substDict = { 1024 "ldrsh_lit_u" : loadImmClassName(False, True, False, 2, True), 1025 "ldrsh_lit" : loadImmClassName(False, False, False, 2, True), 1026 "ldrh_lit_u" : loadImmClassName(False, True, False, 2), 1027 "ldrh_lit" : loadImmClassName(False, False, False, 2), 1028 "ldrsh_radd" : loadRegClassName(False, True, False, 2, True), 1029 "ldrh_radd" : loadRegClassName(False, True, False, 2), 1030 "ldrsh_iw" : loadImmClassName(True, False, True, 2, True), 1031 "ldrsh_iuw" : loadImmClassName(True, True, True, 2, True), 1032 "ldrsh_ip" : loadImmClassName(False, False, False, 2, True), 1033 "ldrsh_ipw" : loadImmClassName(False, False, True, 2, True), 1034 "ldrsh_ipuw" : loadImmClassName(False, True, True, 2, True), 1035 "ldrsh_iadd" : loadImmClassName(False, True, False, 2, True), 1036 "ldrh_iw" : loadImmClassName(True, False, True, 2), 1037 "ldrh_iuw" : loadImmClassName(True, True, True, 2), 1038 "ldrh_ip" : loadImmClassName(False, False, False, 2), 1039 "ldrh_ipw" : loadImmClassName(False, False, True, 2), 1040 "ldrh_ipuw" : loadImmClassName(False, True, True, 2), 1041 "ldrh_iadd" : loadImmClassName(False, True, False, 2), 1042 "ldrht" : loadImmClassName(False, True, False, 2, user=True), 1043 "ldrsht" : loadImmClassName(False, True, False, 2, True, user=True), 1044 "pldw_radd" : "PLDW_" + loadRegClassName(False, True, False, 1), 1045 "pld_radd" : "PLD_" + loadRegClassName(False, True, False, 1), 1046 "pldw_isub" : "PLDW_" + loadImmClassName(False, False, False, 1), 1047 "pld_isub" : "PLD_" + loadImmClassName(False, False, False, 1), 1048 "pldw_iadd" : "PLDW_" + loadImmClassName(False, True, False, 1), 1049 "pld_iadd" : "PLD_" + loadImmClassName(False, True, False, 1) 1050 } 1051 decode_block = decode % substDict 1052}}; 1053 1054def format Thumb16MemReg() {{ 1055 decode = ''' 1056 { 1057 const uint32_t opb = bits(machInst, 11, 9); 1058 const uint32_t rt = bits(machInst, 2, 0); 1059 const uint32_t rn = bits(machInst, 5, 3); 1060 const uint32_t rm = bits(machInst, 8, 6); 1061 switch (opb) { 1062 case 0x0: 1063 return new %(str)s(machInst, rt, rn, true, 0, LSL, rm); 1064 case 0x1: 1065 return new %(strh)s(machInst, rt, rn, true, 0, LSL, rm); 1066 case 0x2: 1067 return new %(strb)s(machInst, rt, rn, true, 0, LSL, rm); 1068 case 0x3: 1069 return new %(ldrsb)s(machInst, rt, rn, true, 0, LSL, rm); 1070 case 0x4: 1071 return new %(ldr)s(machInst, rt, rn, true, 0, LSL, rm); 1072 case 0x5: 1073 return new %(ldrh)s(machInst, rt, rn, true, 0, LSL, rm); 1074 case 0x6: 1075 return new %(ldrb)s(machInst, rt, rn, true, 0, LSL, rm); 1076 case 0x7: 1077 return new %(ldrsh)s(machInst, rt, rn, true, 0, LSL, rm); 1078 default: 1079 M5_UNREACHABLE; 1080 } 1081 } 1082 ''' 1083 classNames = { 1084 "str" : storeRegClassName(False, True, False), 1085 "strh" : storeRegClassName(False, True, False, size=2), 1086 "strb" : storeRegClassName(False, True, False, size=1), 1087 "ldrsb" : loadRegClassName(False, True, False, sign=True, size=1), 1088 "ldr" : loadRegClassName(False, True, False), 1089 "ldrh" : loadRegClassName(False, True, False, size=2), 1090 "ldrb" : loadRegClassName(False, True, False, size=1), 1091 "ldrsh" : loadRegClassName(False, True, False, sign=True, size=2), 1092 } 1093 decode_block = decode % classNames 1094}}; 1095 1096def format Thumb16MemImm() {{ 1097 decode = ''' 1098 { 1099 const uint32_t opa = bits(machInst, 15, 12); 1100 const uint32_t opb = bits(machInst, 11, 9); 1101 const uint32_t lrt = bits(machInst, 2, 0); 1102 const uint32_t lrn = bits(machInst, 5, 3); 1103 const uint32_t hrt = bits(machInst, 10, 8); 1104 const uint32_t imm5 = bits(machInst, 10, 6); 1105 const uint32_t imm8 = bits(machInst, 7, 0); 1106 const bool load = bits(opb, 2); 1107 switch (opa) { 1108 case 0x6: 1109 if (load) { 1110 return new %(ldr)s(machInst, lrt, lrn, true, imm5 << 2); 1111 } else { 1112 return new %(str)s(machInst, lrt, lrn, true, imm5 << 2); 1113 } 1114 case 0x7: 1115 if (load) { 1116 return new %(ldrb)s(machInst, lrt, lrn, true, imm5); 1117 } else { 1118 return new %(strb)s(machInst, lrt, lrn, true, imm5); 1119 } 1120 case 0x8: 1121 if (load) { 1122 return new %(ldrh)s(machInst, lrt, lrn, true, imm5 << 1); 1123 } else { 1124 return new %(strh)s(machInst, lrt, lrn, true, imm5 << 1); 1125 } 1126 case 0x9: 1127 if (load) { 1128 return new %(ldr)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 1129 } else { 1130 return new %(str)s(machInst, hrt, INTREG_SP, true, imm8 << 2); 1131 } 1132 default: 1133 return new Unknown(machInst); 1134 } 1135 } 1136 ''' 1137 classNames = { 1138 "ldr" : loadImmClassName(False, True, False), 1139 "str" : storeImmClassName(False, True, False), 1140 "ldrh" : loadImmClassName(False, True, False, size=2), 1141 "strh" : storeImmClassName(False, True, False, size=2), 1142 "ldrb" : loadImmClassName(False, True, False, size=1), 1143 "strb" : storeImmClassName(False, True, False, size=1), 1144 } 1145 decode_block = decode % classNames 1146}}; 1147 1148def format Thumb16MemLit() {{ 1149 decode_block = ''' 1150 { 1151 const uint32_t rt = bits(machInst, 10, 8); 1152 const uint32_t imm8 = bits(machInst, 7, 0); 1153 return new %s(machInst, rt, INTREG_PC, true, imm8 << 2); 1154 } 1155 ''' % loadImmClassName(False, True, False) 1156}}; 1157
|