Commit f6548c0a4b751852b9dcb341e3974e049a45a518

Authored by malc
1 parent 4f4a67ae

PPC 32/64 GUEST_BASE support

Signed-off-by: malc <av1474@comtv.ru>
configure
... ... @@ -592,6 +592,9 @@ case &quot;$cpu&quot; in
592 592 arm*)
593 593 host_guest_base="yes"
594 594 ;;
  595 + ppc*)
  596 + host_guest_base="yes"
  597 + ;;
595 598 esac
596 599  
597 600 [ -z "$guest_base" ] && guest_base="$host_guest_base"
... ...
tcg/ppc/tcg-target.c
... ... @@ -42,6 +42,16 @@ static uint8_t *tb_ret_addr;
42 42 #define ADDEND_OFFSET 4
43 43 #endif
44 44  
  45 +#ifndef GUEST_BASE
  46 +#define GUEST_BASE 0
  47 +#endif
  48 +
  49 +#ifdef CONFIG_USE_GUEST_BASE
  50 +#define TCG_GUEST_BASE_REG 30
  51 +#else
  52 +#define TCG_GUEST_BASE_REG 0
  53 +#endif
  54 +
45 55 #ifndef NDEBUG
46 56 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
47 57 "r0",
... ... @@ -501,7 +511,7 @@ static void *qemu_st_helpers[4] = {
501 511  
502 512 static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
503 513 {
504   - int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
  514 + int addr_reg, data_reg, data_reg2, r0, r1, rbase, mem_index, s_bits, bswap;
505 515 #ifdef CONFIG_SOFTMMU
506 516 int r2;
507 517 void *label1_ptr, *label2_ptr;
... ... @@ -526,6 +536,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
526 536 r0 = 3;
527 537 r1 = 4;
528 538 r2 = 0;
  539 + rbase = 0;
529 540  
530 541 tcg_out32 (s, (RLWINM
531 542 | RA (r0)
... ... @@ -631,6 +642,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
631 642 #else /* !CONFIG_SOFTMMU */
632 643 r0 = addr_reg;
633 644 r1 = 3;
  645 + rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
634 646 #endif
635 647  
636 648 #ifdef TARGET_WORDS_BIGENDIAN
... ... @@ -638,37 +650,47 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
638 650 #else
639 651 bswap = 1;
640 652 #endif
  653 +
641 654 switch (opc) {
642 655 default:
643 656 case 0:
644   - tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
  657 + tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
645 658 break;
646 659 case 0|4:
647   - tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
  660 + tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
648 661 tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
649 662 break;
650 663 case 1:
651   - if (bswap) tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
652   - else tcg_out32 (s, LHZ | RT (data_reg) | RA (r0));
  664 + if (bswap)
  665 + tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
  666 + else
  667 + tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
653 668 break;
654 669 case 1|4:
655 670 if (bswap) {
656   - tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
  671 + tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
657 672 tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
658 673 }
659   - else tcg_out32 (s, LHA | RT (data_reg) | RA (r0));
  674 + else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
660 675 break;
661 676 case 2:
662   - if (bswap) tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
663   - else tcg_out32 (s, LWZ | RT (data_reg)| RA (r0));
  677 + if (bswap)
  678 + tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
  679 + else
  680 + tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
664 681 break;
665 682 case 3:
666 683 if (bswap) {
667   - tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
668   - tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
669   - tcg_out32 (s, LWBRX | RT (data_reg2) | RB (r1));
  684 + tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
  685 + tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
  686 + tcg_out32 (s, LWBRX | TAB (data_reg2, rbase, r1));
670 687 }
671 688 else {
  689 +#ifdef CONFIG_USE_GUEST_BASE
  690 + tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
  691 + tcg_out32 (s, LWZX | TAB (data_reg2, rbase, r0));
  692 + tcg_out32 (s, LWZX | TAB (data_reg, rbase, r1));
  693 +#else
672 694 if (r0 == data_reg2) {
673 695 tcg_out32 (s, LWZ | RT (0) | RA (r0));
674 696 tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
... ... @@ -678,6 +700,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
678 700 tcg_out32 (s, LWZ | RT (data_reg2) | RA (r0));
679 701 tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
680 702 }
  703 +#endif
681 704 }
682 705 break;
683 706 }
... ... @@ -689,7 +712,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
689 712  
690 713 static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
691 714 {
692   - int addr_reg, r0, r1, data_reg, data_reg2, mem_index, bswap;
  715 + int addr_reg, r0, r1, data_reg, data_reg2, mem_index, bswap, rbase;
693 716 #ifdef CONFIG_SOFTMMU
694 717 int r2, ir;
695 718 void *label1_ptr, *label2_ptr;
... ... @@ -713,6 +736,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
713 736 r0 = 3;
714 737 r1 = 4;
715 738 r2 = 0;
  739 + rbase = 0;
716 740  
717 741 tcg_out32 (s, (RLWINM
718 742 | RA (r0)
... ... @@ -819,8 +843,9 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
819 843 /* r0 = env->tlb_table[mem_index][index].addend + addr */
820 844  
821 845 #else /* !CONFIG_SOFTMMU */
822   - r1 = 3;
823 846 r0 = addr_reg;
  847 + r1 = 3;
  848 + rbase = GUEST_BASE ? rbase : 0;
824 849 #endif
825 850  
826 851 #ifdef TARGET_WORDS_BIGENDIAN
... ... @@ -830,25 +855,35 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
830 855 #endif
831 856 switch (opc) {
832 857 case 0:
833   - tcg_out32 (s, STB | RS (data_reg) | RA (r0));
  858 + tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
834 859 break;
835 860 case 1:
836   - if (bswap) tcg_out32 (s, STHBRX | RS (data_reg) | RA (0) | RB (r0));
837   - else tcg_out32 (s, STH | RS (data_reg) | RA (r0));
  861 + if (bswap)
  862 + tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
  863 + else
  864 + tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
838 865 break;
839 866 case 2:
840   - if (bswap) tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
841   - else tcg_out32 (s, STW | RS (data_reg) | RA (r0));
  867 + if (bswap)
  868 + tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
  869 + else
  870 + tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
842 871 break;
843 872 case 3:
844 873 if (bswap) {
845 874 tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
846   - tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
847   - tcg_out32 (s, STWBRX | RS (data_reg2) | RA (0) | RB (r1));
  875 + tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
  876 + tcg_out32 (s, STWBRX | SAB (data_reg2, rbase, r1));
848 877 }
849 878 else {
  879 +#ifdef CONFIG_USE_GUEST_BASE
  880 + tcg_out32 (s, STWX | SAB (data_reg2, rbase, r0));
  881 + tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
  882 + tcg_out32 (s, STWX | SAB (data_reg, rbase, r1));
  883 +#else
850 884 tcg_out32 (s, STW | RS (data_reg2) | RA (r0));
851 885 tcg_out32 (s, STW | RS (data_reg) | RA (r0) | 4);
  886 +#endif
852 887 }
853 888 break;
854 889 }
... ... @@ -890,6 +925,10 @@ void tcg_target_qemu_prologue (TCGContext *s)
890 925 );
891 926 tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size + LR_OFFSET));
892 927  
  928 +#ifdef CONFIG_USE_GUEST_BASE
  929 + tcg_out_movi (s, TCG_TYPE_I32, TCG_GUEST_BASE_REG, GUEST_BASE);
  930 +#endif
  931 +
893 932 tcg_out32 (s, MTSPR | RS (3) | CTR);
894 933 tcg_out32 (s, BCCTR | BO_ALWAYS);
895 934 tb_ret_addr = s->code_ptr;
... ... @@ -1532,6 +1571,9 @@ void tcg_target_init(TCGContext *s)
1532 1571 #ifdef __linux__
1533 1572 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13);
1534 1573 #endif
  1574 +#ifdef CONFIG_USE_GUEST_BASE
  1575 + tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
  1576 +#endif
1535 1577  
1536 1578 tcg_add_target_add_op_defs(ppc_op_defs);
1537 1579 }
... ...
tcg/ppc/tcg-target.h
... ... @@ -85,3 +85,5 @@ enum {
85 85 #define TCG_AREG0 TCG_REG_R27
86 86 #define TCG_AREG1 TCG_REG_R24
87 87 #define TCG_AREG2 TCG_REG_R25
  88 +
  89 +#define TCG_TARGET_HAS_GUEST_BASE
... ...
tcg/ppc64/tcg-target.c
... ... @@ -42,6 +42,16 @@ static uint8_t *tb_ret_addr;
42 42 #define CMP_L (1<<21)
43 43 #endif
44 44  
  45 +#ifndef GUEST_BASE
  46 +#define GUEST_BASE 0
  47 +#endif
  48 +
  49 +#ifdef CONFIG_USE_GUEST_BASE
  50 +#define TCG_GUEST_BASE_REG 30
  51 +#else
  52 +#define TCG_GUEST_BASE_REG 0
  53 +#endif
  54 +
45 55 #ifndef NDEBUG
46 56 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
47 57 "r0",
... ... @@ -588,7 +598,7 @@ static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
588 598  
589 599 static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
590 600 {
591   - int addr_reg, data_reg, r0, r1, mem_index, s_bits, bswap;
  601 + int addr_reg, data_reg, r0, r1, rbase, mem_index, s_bits, bswap;
592 602 #ifdef CONFIG_SOFTMMU
593 603 int r2;
594 604 void *label1_ptr, *label2_ptr;
... ... @@ -603,6 +613,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
603 613 r0 = 3;
604 614 r1 = 4;
605 615 r2 = 0;
  616 + rbase = 0;
606 617  
607 618 tcg_out_tlb_read (s, r0, r1, r2, addr_reg, s_bits,
608 619 offsetof (CPUState, tlb_table[mem_index][0].addr_read));
... ... @@ -663,6 +674,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
663 674 #endif
664 675 r0 = addr_reg;
665 676 r1 = 3;
  677 + rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
666 678 #endif
667 679  
668 680 #ifdef TARGET_WORDS_BIGENDIAN
... ... @@ -673,35 +685,48 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
673 685 switch (opc) {
674 686 default:
675 687 case 0:
676   - tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
  688 + tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
677 689 break;
678 690 case 0|4:
679   - tcg_out32 (s, LBZ | RT (data_reg) | RA (r0));
  691 + tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
680 692 tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
681 693 break;
682 694 case 1:
683   - if (bswap) tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
684   - else tcg_out32 (s, LHZ | RT (data_reg) | RA (r0));
  695 + if (bswap)
  696 + tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
  697 + else
  698 + tcg_out32 (s, LHZX | TAB (data_reg, rbase, r0));
685 699 break;
686 700 case 1|4:
687 701 if (bswap) {
688   - tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0));
  702 + tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
689 703 tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg));
690 704 }
691   - else tcg_out32 (s, LHA | RT (data_reg) | RA (r0));
  705 + else tcg_out32 (s, LHAX | TAB (data_reg, rbase, r0));
692 706 break;
693 707 case 2:
694   - if (bswap) tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
695   - else tcg_out32 (s, LWZ | RT (data_reg)| RA (r0));
  708 + if (bswap)
  709 + tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
  710 + else
  711 + tcg_out32 (s, LWZX | TAB (data_reg, rbase, r0));
696 712 break;
697 713 case 2|4:
698 714 if (bswap) {
699   - tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
  715 + tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
700 716 tcg_out32 (s, EXTSW | RA (data_reg) | RS (data_reg));
701 717 }
702   - else tcg_out32 (s, LWA | RT (data_reg)| RA (r0));
  718 + else tcg_out32 (s, LWAX | TAB (data_reg, rbase, r0));
703 719 break;
704 720 case 3:
  721 +#ifdef CONFIG_USE_GUEST_BASE
  722 + if (bswap) {
  723 + tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
  724 + tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
  725 + tcg_out32 (s, LWBRX | TAB ( r1, rbase, r1));
  726 + tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
  727 + }
  728 + else tcg_out32 (s, LDX | TAB (data_reg, rbase, r0));
  729 +#else
705 730 if (bswap) {
706 731 tcg_out_movi32 (s, 0, 4);
707 732 tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0));
... ... @@ -709,6 +734,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
709 734 tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
710 735 }
711 736 else tcg_out32 (s, LD | RT (data_reg) | RA (r0));
  737 +#endif
712 738 break;
713 739 }
714 740  
... ... @@ -719,7 +745,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
719 745  
720 746 static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
721 747 {
722   - int addr_reg, r0, r1, data_reg, mem_index, bswap;
  748 + int addr_reg, r0, r1, rbase, data_reg, mem_index, bswap;
723 749 #ifdef CONFIG_SOFTMMU
724 750 int r2;
725 751 void *label1_ptr, *label2_ptr;
... ... @@ -733,6 +759,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
733 759 r0 = 3;
734 760 r1 = 4;
735 761 r2 = 0;
  762 + rbase = 0;
736 763  
737 764 tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc,
738 765 offsetof (CPUState, tlb_table[mem_index][0].addr_write));
... ... @@ -775,6 +802,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
775 802 #endif
776 803 r1 = 3;
777 804 r0 = addr_reg;
  805 + rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
778 806 #endif
779 807  
780 808 #ifdef TARGET_WORDS_BIGENDIAN
... ... @@ -784,24 +812,28 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
784 812 #endif
785 813 switch (opc) {
786 814 case 0:
787   - tcg_out32 (s, STB | RS (data_reg) | RA (r0));
  815 + tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
788 816 break;
789 817 case 1:
790   - if (bswap) tcg_out32 (s, STHBRX | RS (data_reg) | RA (0) | RB (r0));
791   - else tcg_out32 (s, STH | RS (data_reg) | RA (r0));
  818 + if (bswap)
  819 + tcg_out32 (s, STHBRX | SAB (data_reg, rbase, r0));
  820 + else
  821 + tcg_out32 (s, STHX | SAB (data_reg, rbase, r0));
792 822 break;
793 823 case 2:
794   - if (bswap) tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
795   - else tcg_out32 (s, STW | RS (data_reg) | RA (r0));
  824 + if (bswap)
  825 + tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
  826 + else
  827 + tcg_out32 (s, STWX | SAB (data_reg, rbase, r0));
796 828 break;
797 829 case 3:
798 830 if (bswap) {
799   - tcg_out32 (s, STWBRX | RS (data_reg) | RA (0) | RB (r0));
  831 + tcg_out32 (s, STWBRX | SAB (data_reg, rbase, r0));
800 832 tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
801 833 tcg_out_rld (s, RLDICL, 0, data_reg, 32, 0);
802   - tcg_out32 (s, STWBRX | RS (0) | RA (0) | RB (r1));
  834 + tcg_out32 (s, STWBRX | SAB (0, rbase, r1));
803 835 }
804   - else tcg_out32 (s, STD | RS (data_reg) | RA (r0));
  836 + else tcg_out32 (s, STDX | SAB (data_reg, rbase, r0));
805 837 break;
806 838 }
807 839  
... ... @@ -844,6 +876,10 @@ void tcg_target_qemu_prologue (TCGContext *s)
844 876 );
845 877 tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 16));
846 878  
  879 +#ifdef CONFIG_USE_GUEST_BASE
  880 + tcg_out_movi (s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);
  881 +#endif
  882 +
847 883 tcg_out32 (s, MTSPR | RS (3) | CTR);
848 884 tcg_out32 (s, BCCTR | BO_ALWAYS);
849 885  
... ... @@ -1498,5 +1534,9 @@ void tcg_target_init (TCGContext *s)
1498 1534 tcg_regset_set_reg (s->reserved_regs, TCG_REG_R2);
1499 1535 tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13);
1500 1536  
  1537 +#ifdef CONFIG_USE_GUEST_BASE
  1538 + tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);
  1539 +#endif
  1540 +
1501 1541 tcg_add_target_add_op_defs (ppc_op_defs);
1502 1542 }
... ...
tcg/ppc64/tcg-target.h
... ... @@ -81,3 +81,5 @@ enum {
81 81 #define TCG_AREG0 TCG_REG_R27
82 82 #define TCG_AREG1 TCG_REG_R24
83 83 #define TCG_AREG2 TCG_REG_R25
  84 +
  85 +#define TCG_TARGET_HAS_GUEST_BASE
... ...