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,6 +592,9 @@ case &quot;$cpu&quot; in
592 arm*) 592 arm*)
593 host_guest_base="yes" 593 host_guest_base="yes"
594 ;; 594 ;;
  595 + ppc*)
  596 + host_guest_base="yes"
  597 + ;;
595 esac 598 esac
596 599
597 [ -z "$guest_base" ] && guest_base="$host_guest_base" 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,6 +42,16 @@ static uint8_t *tb_ret_addr;
42 #define ADDEND_OFFSET 4 42 #define ADDEND_OFFSET 4
43 #endif 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 #ifndef NDEBUG 55 #ifndef NDEBUG
46 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { 56 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
47 "r0", 57 "r0",
@@ -501,7 +511,7 @@ static void *qemu_st_helpers[4] = { @@ -501,7 +511,7 @@ static void *qemu_st_helpers[4] = {
501 511
502 static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) 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 #ifdef CONFIG_SOFTMMU 515 #ifdef CONFIG_SOFTMMU
506 int r2; 516 int r2;
507 void *label1_ptr, *label2_ptr; 517 void *label1_ptr, *label2_ptr;
@@ -526,6 +536,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) @@ -526,6 +536,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
526 r0 = 3; 536 r0 = 3;
527 r1 = 4; 537 r1 = 4;
528 r2 = 0; 538 r2 = 0;
  539 + rbase = 0;
529 540
530 tcg_out32 (s, (RLWINM 541 tcg_out32 (s, (RLWINM
531 | RA (r0) 542 | RA (r0)
@@ -631,6 +642,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) @@ -631,6 +642,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
631 #else /* !CONFIG_SOFTMMU */ 642 #else /* !CONFIG_SOFTMMU */
632 r0 = addr_reg; 643 r0 = addr_reg;
633 r1 = 3; 644 r1 = 3;
  645 + rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
634 #endif 646 #endif
635 647
636 #ifdef TARGET_WORDS_BIGENDIAN 648 #ifdef TARGET_WORDS_BIGENDIAN
@@ -638,37 +650,47 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) @@ -638,37 +650,47 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
638 #else 650 #else
639 bswap = 1; 651 bswap = 1;
640 #endif 652 #endif
  653 +
641 switch (opc) { 654 switch (opc) {
642 default: 655 default:
643 case 0: 656 case 0:
644 - tcg_out32 (s, LBZ | RT (data_reg) | RA (r0)); 657 + tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
645 break; 658 break;
646 case 0|4: 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 tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg)); 661 tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
649 break; 662 break;
650 case 1: 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 break; 668 break;
654 case 1|4: 669 case 1|4:
655 if (bswap) { 670 if (bswap) {
656 - tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0)); 671 + tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
657 tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg)); 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 break; 675 break;
661 case 2: 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 break; 681 break;
665 case 3: 682 case 3:
666 if (bswap) { 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 else { 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 if (r0 == data_reg2) { 694 if (r0 == data_reg2) {
673 tcg_out32 (s, LWZ | RT (0) | RA (r0)); 695 tcg_out32 (s, LWZ | RT (0) | RA (r0));
674 tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4); 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,6 +700,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
678 tcg_out32 (s, LWZ | RT (data_reg2) | RA (r0)); 700 tcg_out32 (s, LWZ | RT (data_reg2) | RA (r0));
679 tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4); 701 tcg_out32 (s, LWZ | RT (data_reg) | RA (r0) | 4);
680 } 702 }
  703 +#endif
681 } 704 }
682 break; 705 break;
683 } 706 }
@@ -689,7 +712,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) @@ -689,7 +712,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
689 712
690 static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) 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 #ifdef CONFIG_SOFTMMU 716 #ifdef CONFIG_SOFTMMU
694 int r2, ir; 717 int r2, ir;
695 void *label1_ptr, *label2_ptr; 718 void *label1_ptr, *label2_ptr;
@@ -713,6 +736,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) @@ -713,6 +736,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
713 r0 = 3; 736 r0 = 3;
714 r1 = 4; 737 r1 = 4;
715 r2 = 0; 738 r2 = 0;
  739 + rbase = 0;
716 740
717 tcg_out32 (s, (RLWINM 741 tcg_out32 (s, (RLWINM
718 | RA (r0) 742 | RA (r0)
@@ -819,8 +843,9 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) @@ -819,8 +843,9 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
819 /* r0 = env->tlb_table[mem_index][index].addend + addr */ 843 /* r0 = env->tlb_table[mem_index][index].addend + addr */
820 844
821 #else /* !CONFIG_SOFTMMU */ 845 #else /* !CONFIG_SOFTMMU */
822 - r1 = 3;  
823 r0 = addr_reg; 846 r0 = addr_reg;
  847 + r1 = 3;
  848 + rbase = GUEST_BASE ? rbase : 0;
824 #endif 849 #endif
825 850
826 #ifdef TARGET_WORDS_BIGENDIAN 851 #ifdef TARGET_WORDS_BIGENDIAN
@@ -830,25 +855,35 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) @@ -830,25 +855,35 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
830 #endif 855 #endif
831 switch (opc) { 856 switch (opc) {
832 case 0: 857 case 0:
833 - tcg_out32 (s, STB | RS (data_reg) | RA (r0)); 858 + tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
834 break; 859 break;
835 case 1: 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 break; 865 break;
839 case 2: 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 break; 871 break;
843 case 3: 872 case 3:
844 if (bswap) { 873 if (bswap) {
845 tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4); 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 else { 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 tcg_out32 (s, STW | RS (data_reg2) | RA (r0)); 884 tcg_out32 (s, STW | RS (data_reg2) | RA (r0));
851 tcg_out32 (s, STW | RS (data_reg) | RA (r0) | 4); 885 tcg_out32 (s, STW | RS (data_reg) | RA (r0) | 4);
  886 +#endif
852 } 887 }
853 break; 888 break;
854 } 889 }
@@ -890,6 +925,10 @@ void tcg_target_qemu_prologue (TCGContext *s) @@ -890,6 +925,10 @@ void tcg_target_qemu_prologue (TCGContext *s)
890 ); 925 );
891 tcg_out32 (s, STW | RS (0) | RA (1) | (frame_size + LR_OFFSET)); 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 tcg_out32 (s, MTSPR | RS (3) | CTR); 932 tcg_out32 (s, MTSPR | RS (3) | CTR);
894 tcg_out32 (s, BCCTR | BO_ALWAYS); 933 tcg_out32 (s, BCCTR | BO_ALWAYS);
895 tb_ret_addr = s->code_ptr; 934 tb_ret_addr = s->code_ptr;
@@ -1532,6 +1571,9 @@ void tcg_target_init(TCGContext *s) @@ -1532,6 +1571,9 @@ void tcg_target_init(TCGContext *s)
1532 #ifdef __linux__ 1571 #ifdef __linux__
1533 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13); 1572 tcg_regset_set_reg(s->reserved_regs, TCG_REG_R13);
1534 #endif 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 tcg_add_target_add_op_defs(ppc_op_defs); 1578 tcg_add_target_add_op_defs(ppc_op_defs);
1537 } 1579 }
tcg/ppc/tcg-target.h
@@ -85,3 +85,5 @@ enum { @@ -85,3 +85,5 @@ enum {
85 #define TCG_AREG0 TCG_REG_R27 85 #define TCG_AREG0 TCG_REG_R27
86 #define TCG_AREG1 TCG_REG_R24 86 #define TCG_AREG1 TCG_REG_R24
87 #define TCG_AREG2 TCG_REG_R25 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,6 +42,16 @@ static uint8_t *tb_ret_addr;
42 #define CMP_L (1<<21) 42 #define CMP_L (1<<21)
43 #endif 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 #ifndef NDEBUG 55 #ifndef NDEBUG
46 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { 56 static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = {
47 "r0", 57 "r0",
@@ -588,7 +598,7 @@ static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2, @@ -588,7 +598,7 @@ static void tcg_out_tlb_read (TCGContext *s, int r0, int r1, int r2,
588 598
589 static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) 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 #ifdef CONFIG_SOFTMMU 602 #ifdef CONFIG_SOFTMMU
593 int r2; 603 int r2;
594 void *label1_ptr, *label2_ptr; 604 void *label1_ptr, *label2_ptr;
@@ -603,6 +613,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) @@ -603,6 +613,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
603 r0 = 3; 613 r0 = 3;
604 r1 = 4; 614 r1 = 4;
605 r2 = 0; 615 r2 = 0;
  616 + rbase = 0;
606 617
607 tcg_out_tlb_read (s, r0, r1, r2, addr_reg, s_bits, 618 tcg_out_tlb_read (s, r0, r1, r2, addr_reg, s_bits,
608 offsetof (CPUState, tlb_table[mem_index][0].addr_read)); 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,6 +674,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
663 #endif 674 #endif
664 r0 = addr_reg; 675 r0 = addr_reg;
665 r1 = 3; 676 r1 = 3;
  677 + rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
666 #endif 678 #endif
667 679
668 #ifdef TARGET_WORDS_BIGENDIAN 680 #ifdef TARGET_WORDS_BIGENDIAN
@@ -673,35 +685,48 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) @@ -673,35 +685,48 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
673 switch (opc) { 685 switch (opc) {
674 default: 686 default:
675 case 0: 687 case 0:
676 - tcg_out32 (s, LBZ | RT (data_reg) | RA (r0)); 688 + tcg_out32 (s, LBZX | TAB (data_reg, rbase, r0));
677 break; 689 break;
678 case 0|4: 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 tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg)); 692 tcg_out32 (s, EXTSB | RA (data_reg) | RS (data_reg));
681 break; 693 break;
682 case 1: 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 break; 699 break;
686 case 1|4: 700 case 1|4:
687 if (bswap) { 701 if (bswap) {
688 - tcg_out32 (s, LHBRX | RT (data_reg) | RB (r0)); 702 + tcg_out32 (s, LHBRX | TAB (data_reg, rbase, r0));
689 tcg_out32 (s, EXTSH | RA (data_reg) | RS (data_reg)); 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 break; 706 break;
693 case 2: 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 break; 712 break;
697 case 2|4: 713 case 2|4:
698 if (bswap) { 714 if (bswap) {
699 - tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0)); 715 + tcg_out32 (s, LWBRX | TAB (data_reg, rbase, r0));
700 tcg_out32 (s, EXTSW | RA (data_reg) | RS (data_reg)); 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 break; 719 break;
704 case 3: 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 if (bswap) { 730 if (bswap) {
706 tcg_out_movi32 (s, 0, 4); 731 tcg_out_movi32 (s, 0, 4);
707 tcg_out32 (s, LWBRX | RT (data_reg) | RB (r0)); 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,6 +734,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
709 tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0); 734 tcg_out_rld (s, RLDIMI, data_reg, r1, 32, 0);
710 } 735 }
711 else tcg_out32 (s, LD | RT (data_reg) | RA (r0)); 736 else tcg_out32 (s, LD | RT (data_reg) | RA (r0));
  737 +#endif
712 break; 738 break;
713 } 739 }
714 740
@@ -719,7 +745,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc) @@ -719,7 +745,7 @@ static void tcg_out_qemu_ld (TCGContext *s, const TCGArg *args, int opc)
719 745
720 static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) 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 #ifdef CONFIG_SOFTMMU 749 #ifdef CONFIG_SOFTMMU
724 int r2; 750 int r2;
725 void *label1_ptr, *label2_ptr; 751 void *label1_ptr, *label2_ptr;
@@ -733,6 +759,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) @@ -733,6 +759,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
733 r0 = 3; 759 r0 = 3;
734 r1 = 4; 760 r1 = 4;
735 r2 = 0; 761 r2 = 0;
  762 + rbase = 0;
736 763
737 tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc, 764 tcg_out_tlb_read (s, r0, r1, r2, addr_reg, opc,
738 offsetof (CPUState, tlb_table[mem_index][0].addr_write)); 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,6 +802,7 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
775 #endif 802 #endif
776 r1 = 3; 803 r1 = 3;
777 r0 = addr_reg; 804 r0 = addr_reg;
  805 + rbase = GUEST_BASE ? TCG_GUEST_BASE_REG : 0;
778 #endif 806 #endif
779 807
780 #ifdef TARGET_WORDS_BIGENDIAN 808 #ifdef TARGET_WORDS_BIGENDIAN
@@ -784,24 +812,28 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc) @@ -784,24 +812,28 @@ static void tcg_out_qemu_st (TCGContext *s, const TCGArg *args, int opc)
784 #endif 812 #endif
785 switch (opc) { 813 switch (opc) {
786 case 0: 814 case 0:
787 - tcg_out32 (s, STB | RS (data_reg) | RA (r0)); 815 + tcg_out32 (s, STBX | SAB (data_reg, rbase, r0));
788 break; 816 break;
789 case 1: 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 break; 822 break;
793 case 2: 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 break; 828 break;
797 case 3: 829 case 3:
798 if (bswap) { 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 tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4); 832 tcg_out32 (s, ADDI | RT (r1) | RA (r0) | 4);
801 tcg_out_rld (s, RLDICL, 0, data_reg, 32, 0); 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 break; 837 break;
806 } 838 }
807 839
@@ -844,6 +876,10 @@ void tcg_target_qemu_prologue (TCGContext *s) @@ -844,6 +876,10 @@ void tcg_target_qemu_prologue (TCGContext *s)
844 ); 876 );
845 tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 16)); 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 tcg_out32 (s, MTSPR | RS (3) | CTR); 883 tcg_out32 (s, MTSPR | RS (3) | CTR);
848 tcg_out32 (s, BCCTR | BO_ALWAYS); 884 tcg_out32 (s, BCCTR | BO_ALWAYS);
849 885
@@ -1498,5 +1534,9 @@ void tcg_target_init (TCGContext *s) @@ -1498,5 +1534,9 @@ void tcg_target_init (TCGContext *s)
1498 tcg_regset_set_reg (s->reserved_regs, TCG_REG_R2); 1534 tcg_regset_set_reg (s->reserved_regs, TCG_REG_R2);
1499 tcg_regset_set_reg (s->reserved_regs, TCG_REG_R13); 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 tcg_add_target_add_op_defs (ppc_op_defs); 1541 tcg_add_target_add_op_defs (ppc_op_defs);
1502 } 1542 }
tcg/ppc64/tcg-target.h
@@ -81,3 +81,5 @@ enum { @@ -81,3 +81,5 @@ enum {
81 #define TCG_AREG0 TCG_REG_R27 81 #define TCG_AREG0 TCG_REG_R27
82 #define TCG_AREG1 TCG_REG_R24 82 #define TCG_AREG1 TCG_REG_R24
83 #define TCG_AREG2 TCG_REG_R25 83 #define TCG_AREG2 TCG_REG_R25
  84 +
  85 +#define TCG_TARGET_HAS_GUEST_BASE