Revision f6548c0a
b/configure | ||
---|---|---|
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" |
b/tcg/ppc/tcg-target.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 |
} |
b/tcg/ppc/tcg-target.h | ||
---|---|---|
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 |
b/tcg/ppc64/tcg-target.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 |
} |
b/tcg/ppc64/tcg-target.h | ||
---|---|---|
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 |
Also available in: Unified diff