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