Revision be5a4eb7

b/tcg/i386/tcg-target.c
704 704
};
705 705
#endif
706 706

  
707
#ifndef CONFIG_USER_ONLY
708
#define GUEST_BASE 0
707
static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo, int datahi,
708
                                   int base, tcg_target_long ofs, int sizeop)
709
{
710
#ifdef TARGET_WORDS_BIGENDIAN
711
    const int bswap = 1;
712
#else
713
    const int bswap = 0;
709 714
#endif
715
    switch (sizeop) {
716
    case 0:
717
        /* movzbl */
718
        tcg_out_modrm_offset(s, OPC_MOVZBL, datalo, base, ofs);
719
        break;
720
    case 0 | 4:
721
        /* movsbl */
722
        tcg_out_modrm_offset(s, OPC_MOVSBL, datalo, base, ofs);
723
        break;
724
    case 1:
725
        /* movzwl */
726
        tcg_out_modrm_offset(s, OPC_MOVZWL, datalo, base, ofs);
727
        if (bswap) {
728
            tcg_out_rolw_8(s, datalo);
729
        }
730
        break;
731
    case 1 | 4:
732
        /* movswl */
733
        tcg_out_modrm_offset(s, OPC_MOVSWL, datalo, base, ofs);
734
        if (bswap) {
735
            tcg_out_rolw_8(s, datalo);
736
            tcg_out_modrm(s, OPC_MOVSWL, datalo, datalo);
737
        }
738
        break;
739
    case 2:
740
        tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
741
        if (bswap) {
742
            tcg_out_bswap32(s, datalo);
743
        }
744
        break;
745
    case 3:
746
        if (bswap) {
747
            int t = datalo;
748
            datalo = datahi;
749
            datahi = t;
750
        }
751
        if (base != datalo) {
752
            tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
753
            tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
754
        } else {
755
            tcg_out_ld(s, TCG_TYPE_I32, datahi, base, ofs + 4);
756
            tcg_out_ld(s, TCG_TYPE_I32, datalo, base, ofs);
757
        }
758
        if (bswap) {
759
            tcg_out_bswap32(s, datalo);
760
            tcg_out_bswap32(s, datahi);
761
        }
762
        break;
763
    default:
764
        tcg_abort();
765
    }
766
}
710 767

  
711 768
/* XXX: qemu_ld and qemu_st could be modified to clobber only EDX and
712 769
   EAX. It will be useful once fixed registers globals are less
......
714 771
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args,
715 772
                            int opc)
716 773
{
717
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
774
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits;
718 775
#if defined(CONFIG_SOFTMMU)
719 776
    uint8_t *label1_ptr, *label2_ptr;
720 777
#endif
......
831 888
    tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
832 889
                         offsetof(CPUTLBEntry, addend) -
833 890
                         offsetof(CPUTLBEntry, addr_read));
891

  
892
    tcg_out_qemu_ld_direct(s, data_reg, data_reg2, r0, 0, opc);
893

  
894
    /* label2: */
895
    *label2_ptr = s->code_ptr - label2_ptr - 1;
834 896
#else
835
    r0 = addr_reg;
897
    tcg_out_qemu_ld_direct(s, data_reg, data_reg2, addr_reg, GUEST_BASE, opc);
836 898
#endif
899
}
837 900

  
901
static void tcg_out_qemu_st_direct(TCGContext *s, int datalo, int datahi,
902
                                   int base, tcg_target_long ofs, int sizeop)
903
{
838 904
#ifdef TARGET_WORDS_BIGENDIAN
839
    bswap = 1;
905
    const int bswap = 1;
840 906
#else
841
    bswap = 0;
907
    const int bswap = 0;
842 908
#endif
843
    switch(opc) {
909
    /* ??? Ideally we wouldn't need a scratch register.  For user-only,
910
       we could perform the bswap twice to restore the original value
911
       instead of moving to the scratch.  But as it is, the L constraint
912
       means that EDX is definitely free here.  */
913
    int scratch = TCG_REG_EDX;
914

  
915
    switch (sizeop) {
844 916
    case 0:
845
        /* movzbl */
846
        tcg_out_modrm_offset(s, OPC_MOVZBL, data_reg, r0, GUEST_BASE);
847
        break;
848
    case 0 | 4:
849
        /* movsbl */
850
        tcg_out_modrm_offset(s, OPC_MOVSBL, data_reg, r0, GUEST_BASE);
917
        tcg_out_modrm_offset(s, OPC_MOVB_EvGv, datalo, base, ofs);
851 918
        break;
852 919
    case 1:
853
        /* movzwl */
854
        tcg_out_modrm_offset(s, OPC_MOVZWL, data_reg, r0, GUEST_BASE);
855
        if (bswap) {
856
            tcg_out_rolw_8(s, data_reg);
857
        }
858
        break;
859
    case 1 | 4:
860
        /* movswl */
861
        tcg_out_modrm_offset(s, OPC_MOVSWL, data_reg, r0, GUEST_BASE);
862 920
        if (bswap) {
863
            tcg_out_rolw_8(s, data_reg);
864

  
865
            /* movswl data_reg, data_reg */
866
            tcg_out_modrm(s, OPC_MOVSWL, data_reg, data_reg);
921
            tcg_out_mov(s, scratch, datalo);
922
            tcg_out_rolw_8(s, scratch);
923
            datalo = scratch;
867 924
        }
925
        /* movw */
926
        tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
927
                             datalo, base, ofs);
868 928
        break;
869 929
    case 2:
870
        tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
871 930
        if (bswap) {
872
            tcg_out_bswap32(s, data_reg);
931
            tcg_out_mov(s, scratch, datalo);
932
            tcg_out_bswap32(s, scratch);
933
            datalo = scratch;
873 934
        }
935
        tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
874 936
        break;
875 937
    case 3:
876 938
        if (bswap) {
877
            int t = data_reg;
878
            data_reg = data_reg2;
879
            data_reg2 = t;
880
        }
881
        if (r0 != data_reg) {
882
            tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
883
            tcg_out_ld(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE + 4);
939
            tcg_out_mov(s, scratch, datahi);
940
            tcg_out_bswap32(s, scratch);
941
            tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs);
942
            tcg_out_mov(s, scratch, datalo);
943
            tcg_out_bswap32(s, scratch);
944
            tcg_out_st(s, TCG_TYPE_I32, scratch, base, ofs + 4);
884 945
        } else {
885
            tcg_out_ld(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE + 4);
886
            tcg_out_ld(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
887
        }
888
        if (bswap) {
889
            tcg_out_bswap32(s, data_reg);
890
            tcg_out_bswap32(s, data_reg2);
946
            tcg_out_st(s, TCG_TYPE_I32, datalo, base, ofs);
947
            tcg_out_st(s, TCG_TYPE_I32, datahi, base, ofs + 4);
891 948
        }
892 949
        break;
893 950
    default:
894 951
        tcg_abort();
895 952
    }
896

  
897
#if defined(CONFIG_SOFTMMU)
898
    /* label2: */
899
    *label2_ptr = s->code_ptr - label2_ptr - 1;
900
#endif
901 953
}
902 954

  
903

  
904 955
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args,
905 956
                            int opc)
906 957
{
907
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits, bswap;
958
    int addr_reg, data_reg, data_reg2, r0, r1, mem_index, s_bits;
908 959
#if defined(CONFIG_SOFTMMU)
909 960
    int stack_adjust;
910 961
    uint8_t *label1_ptr, *label2_ptr;
......
1041 1092
    tcg_out_modrm_offset(s, OPC_ADD_GvEv, r0, r1,
1042 1093
                         offsetof(CPUTLBEntry, addend) -
1043 1094
                         offsetof(CPUTLBEntry, addr_write));
1044
#else
1045
    r0 = addr_reg;
1046
#endif
1047 1095

  
1048
#ifdef TARGET_WORDS_BIGENDIAN
1049
    bswap = 1;
1050
#else
1051
    bswap = 0;
1052
#endif
1053
    switch(opc) {
1054
    case 0:
1055
        tcg_out_modrm_offset(s, OPC_MOVB_EvGv, data_reg, r0, GUEST_BASE);
1056
        break;
1057
    case 1:
1058
        if (bswap) {
1059
            tcg_out_mov(s, r1, data_reg);
1060
            tcg_out_rolw_8(s, r1);
1061
            data_reg = r1;
1062
        }
1063
        /* movw */
1064
        tcg_out_modrm_offset(s, OPC_MOVL_EvGv | P_DATA16,
1065
                             data_reg, r0, GUEST_BASE);
1066
        break;
1067
    case 2:
1068
        if (bswap) {
1069
            tcg_out_mov(s, r1, data_reg);
1070
            tcg_out_bswap32(s, r1);
1071
            data_reg = r1;
1072
        }
1073
        tcg_out_st(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
1074
        break;
1075
    case 3:
1076
        if (bswap) {
1077
            tcg_out_mov(s, r1, data_reg2);
1078
            tcg_out_bswap32(s, r1);
1079
            tcg_out_st(s, TCG_TYPE_I32, r1, r0, GUEST_BASE);
1080
            tcg_out_mov(s, r1, data_reg);
1081
            tcg_out_bswap32(s, r1);
1082
            tcg_out_st(s, TCG_TYPE_I32, r1, r0, GUEST_BASE + 4);
1083
        } else {
1084
            tcg_out_st(s, TCG_TYPE_I32, data_reg, r0, GUEST_BASE);
1085
            tcg_out_st(s, TCG_TYPE_I32, data_reg2, r0, GUEST_BASE + 4);
1086
        }
1087
        break;
1088
    default:
1089
        tcg_abort();
1090
    }
1096
    tcg_out_qemu_st_direct(s, data_reg, data_reg2, r0, 0, opc);
1091 1097

  
1092
#if defined(CONFIG_SOFTMMU)
1093 1098
    /* label2: */
1094 1099
    *label2_ptr = s->code_ptr - label2_ptr - 1;
1100
#else
1101
    tcg_out_qemu_st_direct(s, data_reg, data_reg2, addr_reg, GUEST_BASE, opc);
1095 1102
#endif
1096 1103
}
1097 1104

  

Also available in: Unified diff