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