Revision f6548c0a tcg/ppc/tcg-target.c

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
}

Also available in: Unified diff