Revision f061b40e tcg/hppa/tcg-target.c

b/tcg/hppa/tcg-target.c
939 939
}
940 940
#endif
941 941

  
942
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
942
static void tcg_out_qemu_ld_direct(TCGContext *s, int datalo_reg, int datahi_reg,
943
                                   int addr_reg, int addend_reg, int opc)
943 944
{
944
    int addr_reg, addr_reg2;
945
    int data_reg, data_reg2;
946
    int r0, r1, mem_index, s_bits, bswap;
947
    tcg_target_long offset;
948
#if defined(CONFIG_SOFTMMU)
949
    int lab1, lab2, argreg;
950
#endif
951

  
952
    data_reg = *args++;
953
    data_reg2 = (opc == 3 ? *args++ : TCG_REG_R0);
954
    addr_reg = *args++;
955
    addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : TCG_REG_R0);
956
    mem_index = *args;
957
    s_bits = opc & 3;
958

  
959
    r0 = TCG_REG_R26;
960
    r1 = TCG_REG_R25;
961

  
962
#if defined(CONFIG_SOFTMMU)
963
    lab1 = gen_new_label();
964
    lab2 = gen_new_label();
965

  
966
    offset = tcg_out_tlb_read(s, r0, r1, addr_reg, addr_reg2, s_bits, lab1,
967
                              offsetof(CPUState,
968
                                       tlb_table[mem_index][0].addr_read));
969

  
970
    /* TLB Hit.  */
971
    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : r1),
972
               offsetof(CPUState, tlb_table[mem_index][0].addend) - offset);
973

  
974
    tcg_out_arith(s, r0, addr_reg, TCG_REG_R20, INSN_ADDL);
975
    offset = TCG_REG_R0;
976
#else
977
    r0 = addr_reg;
978
    offset = GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_R0;
979
#endif
980

  
981 945
#ifdef TARGET_WORDS_BIGENDIAN
982
    bswap = 0;
946
    const int bswap = 0;
983 947
#else
984
    bswap = 1;
948
    const int bswap = 1;
985 949
#endif
950

  
986 951
    switch (opc) {
987 952
    case 0:
988
        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDBX);
953
        tcg_out_ldst_index(s, datalo_reg, addr_reg, addend_reg, INSN_LDBX);
989 954
        break;
990 955
    case 0 | 4:
991
        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDBX);
992
        tcg_out_ext8s(s, data_reg, data_reg);
956
        tcg_out_ldst_index(s, datalo_reg, addr_reg, addend_reg, INSN_LDBX);
957
        tcg_out_ext8s(s, datalo_reg, datalo_reg);
993 958
        break;
994 959
    case 1:
995
        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDHX);
960
        tcg_out_ldst_index(s, datalo_reg, addr_reg, addend_reg, INSN_LDHX);
996 961
        if (bswap) {
997
            tcg_out_bswap16(s, data_reg, data_reg, 0);
962
            tcg_out_bswap16(s, datalo_reg, datalo_reg, 0);
998 963
        }
999 964
        break;
1000 965
    case 1 | 4:
1001
        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDHX);
966
        tcg_out_ldst_index(s, datalo_reg, addr_reg, addend_reg, INSN_LDHX);
1002 967
        if (bswap) {
1003
            tcg_out_bswap16(s, data_reg, data_reg, 1);
968
            tcg_out_bswap16(s, datalo_reg, datalo_reg, 1);
1004 969
        } else {
1005
            tcg_out_ext16s(s, data_reg, data_reg);
970
            tcg_out_ext16s(s, datalo_reg, datalo_reg);
1006 971
        }
1007 972
        break;
1008 973
    case 2:
1009
        tcg_out_ldst_index(s, data_reg, r0, offset, INSN_LDWX);
974
        tcg_out_ldst_index(s, datalo_reg, addr_reg, addend_reg, INSN_LDWX);
1010 975
        if (bswap) {
1011
            tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
976
            tcg_out_bswap32(s, datalo_reg, datalo_reg, TCG_REG_R20);
1012 977
        }
1013 978
        break;
1014 979
    case 3:
1015 980
        if (bswap) {
1016
            int t = data_reg2;
1017
            data_reg2 = data_reg;
1018
            data_reg = t;
981
            int t = datahi_reg;
982
            datahi_reg = datalo_reg;
983
            datalo_reg = t;
1019 984
        }
1020
        if (offset == TCG_REG_R0) {
1021
            /* Make sure not to clobber the base register.  */
1022
            if (data_reg2 == r0) {
1023
                tcg_out_ldst(s, data_reg, r0, 4, INSN_LDW);
1024
                tcg_out_ldst(s, data_reg2, r0, 0, INSN_LDW);
1025
            } else {
1026
                tcg_out_ldst(s, data_reg2, r0, 0, INSN_LDW);
1027
                tcg_out_ldst(s, data_reg, r0, 4, INSN_LDW);
1028
            }
985
        /* We can't access the low-part with a reg+reg addressing mode,
986
           so perform the addition now and use reg_ofs addressing mode.  */
987
        if (addend_reg != TCG_REG_R0) {
988
            tcg_out_arith(s, TCG_REG_R20, addr_reg, addend_reg, INSN_ADD);
989
            addr_reg = TCG_REG_R20;
990
	}
991
        /* Make sure not to clobber the base register.  */
992
        if (datahi_reg == addr_reg) {
993
            tcg_out_ldst(s, datalo_reg, addr_reg, 4, INSN_LDW);
994
            tcg_out_ldst(s, datahi_reg, addr_reg, 0, INSN_LDW);
1029 995
        } else {
1030
            tcg_out_addi2(s, TCG_REG_R20, r0, 4);
1031
            tcg_out_ldst_index(s, data_reg2, r0, offset, INSN_LDWX);
1032
            tcg_out_ldst_index(s, data_reg, TCG_REG_R20, offset, INSN_LDWX);
996
            tcg_out_ldst(s, datahi_reg, addr_reg, 0, INSN_LDW);
997
            tcg_out_ldst(s, datalo_reg, addr_reg, 4, INSN_LDW);
1033 998
        }
1034 999
        if (bswap) {
1035
            tcg_out_bswap32(s, data_reg, data_reg, TCG_REG_R20);
1036
            tcg_out_bswap32(s, data_reg2, data_reg2, TCG_REG_R20);
1000
            tcg_out_bswap32(s, datalo_reg, datalo_reg, TCG_REG_R20);
1001
            tcg_out_bswap32(s, datahi_reg, datahi_reg, TCG_REG_R20);
1037 1002
        }
1038 1003
        break;
1039 1004
    default:
1040 1005
        tcg_abort();
1041 1006
    }
1007
}
1008

  
1009
static void tcg_out_qemu_ld(TCGContext *s, const TCGArg *args, int opc)
1010
{
1011
    int datalo_reg = *args++;
1012
    /* Note that datahi_reg is only used for 64-bit loads.  */
1013
    int datahi_reg = (opc == 3 ? *args++ : TCG_REG_R0);
1014
    int addrlo_reg = *args++;
1042 1015

  
1043 1016
#if defined(CONFIG_SOFTMMU)
1017
    /* Note that addrhi_reg is only used for 64-bit guests.  */
1018
    int addrhi_reg = (TARGET_LONG_BITS == 64 ? *args++ : TCG_REG_R0);
1019
    int mem_index = *args;
1020
    int lab1, lab2, argreg, offset;
1021

  
1022
    lab1 = gen_new_label();
1023
    lab2 = gen_new_label();
1024

  
1025
    offset = offsetof(CPUState, tlb_table[mem_index][0].addr_read);
1026
    offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg, addrhi_reg,
1027
                              opc & 3, lab1, offset);
1028

  
1029
    /* TLB Hit.  */
1030
    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : TCG_REG_R25),
1031
               offsetof(CPUState, tlb_table[mem_index][0].addend) - offset);
1032
    tcg_out_qemu_ld_direct(s, datalo_reg, datahi_reg, addrlo_reg, TCG_REG_R20, opc);
1044 1033
    tcg_out_branch(s, lab2, 1);
1045 1034

  
1046 1035
    /* TLB Miss.  */
......
1048 1037
    tcg_out_label(s, lab1, (tcg_target_long)s->code_ptr);
1049 1038

  
1050 1039
    argreg = TCG_REG_R26;
1051
    tcg_out_mov(s, argreg--, addr_reg);
1040
    tcg_out_mov(s, argreg--, addrlo_reg);
1052 1041
    if (TARGET_LONG_BITS == 64) {
1053
        tcg_out_mov(s, argreg--, addr_reg2);
1042
        tcg_out_mov(s, argreg--, addrhi_reg);
1054 1043
    }
1055 1044
    tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
1056 1045

  
1057
    tcg_out_call(s, qemu_ld_helpers[s_bits]);
1046
    tcg_out_call(s, qemu_ld_helpers[opc & 3]);
1058 1047

  
1059 1048
    switch (opc) {
1060 1049
    case 0:
1061
        tcg_out_andi(s, data_reg, TCG_REG_RET0, 0xff);
1050
        tcg_out_andi(s, datalo_reg, TCG_REG_RET0, 0xff);
1062 1051
        break;
1063 1052
    case 0 | 4:
1064
        tcg_out_ext8s(s, data_reg, TCG_REG_RET0);
1053
        tcg_out_ext8s(s, datalo_reg, TCG_REG_RET0);
1065 1054
        break;
1066 1055
    case 1:
1067
        tcg_out_andi(s, data_reg, TCG_REG_RET0, 0xffff);
1056
        tcg_out_andi(s, datalo_reg, TCG_REG_RET0, 0xffff);
1068 1057
        break;
1069 1058
    case 1 | 4:
1070
        tcg_out_ext16s(s, data_reg, TCG_REG_RET0);
1059
        tcg_out_ext16s(s, datalo_reg, TCG_REG_RET0);
1071 1060
        break;
1072 1061
    case 2:
1073 1062
    case 2 | 4:
1074
        tcg_out_mov(s, data_reg, TCG_REG_RET0);
1063
        tcg_out_mov(s, datalo_reg, TCG_REG_RET0);
1075 1064
        break;
1076 1065
    case 3:
1077
        tcg_out_mov(s, data_reg, TCG_REG_RET0);
1078
        tcg_out_mov(s, data_reg2, TCG_REG_RET1);
1066
        tcg_out_mov(s, datahi_reg, TCG_REG_RET0);
1067
        tcg_out_mov(s, datalo_reg, TCG_REG_RET1);
1079 1068
        break;
1080 1069
    default:
1081 1070
        tcg_abort();
......
1083 1072

  
1084 1073
    /* label2: */
1085 1074
    tcg_out_label(s, lab2, (tcg_target_long)s->code_ptr);
1075
#else
1076
    tcg_out_qemu_ld_direct(s, datalo_reg, datahi_reg, addrlo_reg,
1077
                           (GUEST_BASE ? TCG_GUEST_BASE_REG : TCG_REG_R0), opc);
1086 1078
#endif
1087 1079
}
1088 1080

  
1089
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
1081
static void tcg_out_qemu_st_direct(TCGContext *s, int datalo_reg, int datahi_reg,
1082
                                   int addr_reg, int opc)
1090 1083
{
1091
    int addr_reg, addr_reg2;
1092
    int data_reg, data_reg2;
1093
    int r0, r1, mem_index, s_bits, bswap;
1094
#if defined(CONFIG_SOFTMMU)
1095
    tcg_target_long offset;
1096
    int lab1, lab2, argreg;
1097
#endif
1098

  
1099
    data_reg = *args++;
1100
    data_reg2 = (opc == 3 ? *args++ : 0);
1101
    addr_reg = *args++;
1102
    addr_reg2 = (TARGET_LONG_BITS == 64 ? *args++ : 0);
1103
    mem_index = *args;
1104
    s_bits = opc;
1105

  
1106
    r0 = TCG_REG_R26;
1107
    r1 = TCG_REG_R25;
1108

  
1109
#if defined(CONFIG_SOFTMMU)
1110
    lab1 = gen_new_label();
1111
    lab2 = gen_new_label();
1112

  
1113
    offset = tcg_out_tlb_read(s, r0, r1, addr_reg, addr_reg2, s_bits, lab1,
1114
                              offsetof(CPUState,
1115
                                       tlb_table[mem_index][0].addr_write));
1116

  
1117
    /* TLB Hit.  */
1118
    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : r1),
1119
               offsetof(CPUState, tlb_table[mem_index][0].addend) - offset);
1120

  
1121
    tcg_out_arith(s, r0, addr_reg, TCG_REG_R20, INSN_ADDL);
1122
#else
1123
    /* There are no indexed stores, so if GUEST_BASE is set
1124
       we must do the add explicitly.  Careful to avoid R20,
1125
       which is used for the bswaps to follow.  */
1126
    if (GUEST_BASE == 0) {
1127
        r0 = addr_reg;
1128
    } else {
1129
        tcg_out_arith(s, TCG_REG_R31, addr_reg, TCG_GUEST_BASE_REG, INSN_ADDL);
1130
        r0 = TCG_REG_R31;
1131
    }
1132
#endif
1133

  
1134 1084
#ifdef TARGET_WORDS_BIGENDIAN
1135
    bswap = 0;
1085
    const int bswap = 0;
1136 1086
#else
1137
    bswap = 1;
1087
    const int bswap = 1;
1138 1088
#endif
1089

  
1139 1090
    switch (opc) {
1140 1091
    case 0:
1141
        tcg_out_ldst(s, data_reg, r0, 0, INSN_STB);
1092
        tcg_out_ldst(s, datalo_reg, addr_reg, 0, INSN_STB);
1142 1093
        break;
1143 1094
    case 1:
1144 1095
        if (bswap) {
1145
            tcg_out_bswap16(s, TCG_REG_R20, data_reg, 0);
1146
            data_reg = TCG_REG_R20;
1096
            tcg_out_bswap16(s, TCG_REG_R20, datalo_reg, 0);
1097
            datalo_reg = TCG_REG_R20;
1147 1098
        }
1148
        tcg_out_ldst(s, data_reg, r0, 0, INSN_STH);
1099
        tcg_out_ldst(s, datalo_reg, addr_reg, 0, INSN_STH);
1149 1100
        break;
1150 1101
    case 2:
1151 1102
        if (bswap) {
1152
            tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);
1153
            data_reg = TCG_REG_R20;
1103
            tcg_out_bswap32(s, TCG_REG_R20, datalo_reg, TCG_REG_R20);
1104
            datalo_reg = TCG_REG_R20;
1154 1105
        }
1155
        tcg_out_ldst(s, data_reg, r0, 0, INSN_STW);
1106
        tcg_out_ldst(s, datalo_reg, addr_reg, 0, INSN_STW);
1156 1107
        break;
1157 1108
    case 3:
1158 1109
        if (bswap) {
1159
            tcg_out_bswap32(s, TCG_REG_R20, data_reg, TCG_REG_R20);
1160
            tcg_out_bswap32(s, TCG_REG_R23, data_reg2, TCG_REG_R23);
1161
            data_reg2 = TCG_REG_R20;
1162
            data_reg = TCG_REG_R23;
1110
            tcg_out_bswap32(s, TCG_REG_R20, datalo_reg, TCG_REG_R20);
1111
            tcg_out_bswap32(s, TCG_REG_R23, datahi_reg, TCG_REG_R23);
1112
            datahi_reg = TCG_REG_R20;
1113
            datalo_reg = TCG_REG_R23;
1163 1114
        }
1164
        tcg_out_ldst(s, data_reg2, r0, 0, INSN_STW);
1165
        tcg_out_ldst(s, data_reg, r0, 4, INSN_STW);
1115
        tcg_out_ldst(s, datahi_reg, addr_reg, 0, INSN_STW);
1116
        tcg_out_ldst(s, datalo_reg, addr_reg, 4, INSN_STW);
1166 1117
        break;
1167 1118
    default:
1168 1119
        tcg_abort();
1169 1120
    }
1170 1121

  
1122
}
1123

  
1124
static void tcg_out_qemu_st(TCGContext *s, const TCGArg *args, int opc)
1125
{
1126
    int datalo_reg = *args++;
1127
    /* Note that datahi_reg is only used for 64-bit loads.  */
1128
    int datahi_reg = (opc == 3 ? *args++ : TCG_REG_R0);
1129
    int addrlo_reg = *args++;
1130

  
1171 1131
#if defined(CONFIG_SOFTMMU)
1132
    /* Note that addrhi_reg is only used for 64-bit guests.  */
1133
    int addrhi_reg = (TARGET_LONG_BITS == 64 ? *args++ : TCG_REG_R0);
1134
    int mem_index = *args;
1135
    int lab1, lab2, argreg, offset;
1136

  
1137
    lab1 = gen_new_label();
1138
    lab2 = gen_new_label();
1139

  
1140
    offset = offsetof(CPUState, tlb_table[mem_index][0].addr_write);
1141
    offset = tcg_out_tlb_read(s, TCG_REG_R26, TCG_REG_R25, addrlo_reg, addrhi_reg,
1142
                              opc, lab1, offset);
1143

  
1144
    /* TLB Hit.  */
1145
    tcg_out_ld(s, TCG_TYPE_PTR, TCG_REG_R20, (offset ? TCG_REG_R1 : TCG_REG_R25),
1146
               offsetof(CPUState, tlb_table[mem_index][0].addend) - offset);
1147

  
1148
    /* There are no indexed stores, so we must do this addition explitly.
1149
       Careful to avoid R20, which is used for the bswaps to follow.  */
1150
    tcg_out_arith(s, TCG_REG_R31, addrlo_reg, TCG_REG_R20, INSN_ADDL);
1151
    tcg_out_qemu_st_direct(s, datalo_reg, datahi_reg, TCG_REG_R31, opc);
1172 1152
    tcg_out_branch(s, lab2, 1);
1173 1153

  
1174 1154
    /* TLB Miss.  */
......
1176 1156
    tcg_out_label(s, lab1, (tcg_target_long)s->code_ptr);
1177 1157

  
1178 1158
    argreg = TCG_REG_R26;
1179
    tcg_out_mov(s, argreg--, addr_reg);
1159
    tcg_out_mov(s, argreg--, addrlo_reg);
1180 1160
    if (TARGET_LONG_BITS == 64) {
1181
        tcg_out_mov(s, argreg--, addr_reg2);
1161
        tcg_out_mov(s, argreg--, addrhi_reg);
1182 1162
    }
1183 1163

  
1184 1164
    switch(opc) {
1185 1165
    case 0:
1186
        tcg_out_andi(s, argreg--, data_reg, 0xff);
1166
        tcg_out_andi(s, argreg--, datalo_reg, 0xff);
1187 1167
        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
1188 1168
        break;
1189 1169
    case 1:
1190
        tcg_out_andi(s, argreg--, data_reg, 0xffff);
1170
        tcg_out_andi(s, argreg--, datalo_reg, 0xffff);
1191 1171
        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
1192 1172
        break;
1193 1173
    case 2:
1194
        tcg_out_mov(s, argreg--, data_reg);
1174
        tcg_out_mov(s, argreg--, datalo_reg);
1195 1175
        tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
1196 1176
        break;
1197 1177
    case 3:
......
1205 1185
            argreg = TCG_REG_R20;
1206 1186
            tcg_out_movi(s, TCG_TYPE_I32, argreg, mem_index);
1207 1187
        }
1208
        tcg_out_mov(s, TCG_REG_R23, data_reg2);
1209
        tcg_out_mov(s, TCG_REG_R24, data_reg);
1188
        tcg_out_mov(s, TCG_REG_R23, datahi_reg);
1189
        tcg_out_mov(s, TCG_REG_R24, datalo_reg);
1210 1190
        tcg_out_st(s, TCG_TYPE_I32, argreg, TCG_REG_SP,
1211 1191
                   TCG_TARGET_CALL_STACK_OFFSET - 4);
1212 1192
        break;
......
1214 1194
        tcg_abort();
1215 1195
    }
1216 1196

  
1217
    tcg_out_call(s, qemu_st_helpers[s_bits]);
1197
    tcg_out_call(s, qemu_st_helpers[opc]);
1218 1198

  
1219 1199
    /* label2: */
1220 1200
    tcg_out_label(s, lab2, (tcg_target_long)s->code_ptr);
1201
#else
1202
    /* There are no indexed stores, so if GUEST_BASE is set we must do the add
1203
       explicitly.  Careful to avoid R20, which is used for the bswaps to follow.  */
1204
    if (GUEST_BASE != 0) {
1205
        tcg_out_arith(s, TCG_REG_R31, addrlo_reg, TCG_GUEST_BASE_REG, INSN_ADDL);
1206
        addrlo_reg = TCG_REG_R31;
1207
    }
1208
    tcg_out_qemu_st_direct(s, datalo_reg, datahi_reg, addrlo_reg, opc);
1221 1209
#endif
1222 1210
}
1223 1211

  

Also available in: Unified diff