Commit f6548c0a4b751852b9dcb341e3974e049a45a518
1 parent
4f4a67ae
PPC 32/64 GUEST_BASE support
Signed-off-by: malc <av1474@comtv.ru>
Showing
5 changed files
with
130 additions
and
41 deletions
configure
@@ -592,6 +592,9 @@ case "$cpu" in | @@ -592,6 +592,9 @@ case "$cpu" 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
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