tcg/loongarch64: Use C_N2_I1 for INDEX_op_qemu_ld_a*_i128
Use new registers for the output, so that we never overlap the input address, which could happen for user-only. This avoids a "tmp = addr + 0" in that case. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Jiajie Chen <c@jia.je> Message-Id: <20230916220151.526140-3-richard.henderson@linaro.org>
This commit is contained in:
parent
fa645b48d3
commit
2b2ae0a42e
@ -38,4 +38,4 @@ C_O1_I2(w, w, wM)
|
||||
C_O1_I2(w, w, wA)
|
||||
C_O1_I3(w, w, w, w)
|
||||
C_O1_I4(r, rZ, rJ, rZ, rZ)
|
||||
C_O2_I1(r, r, r)
|
||||
C_N2_I1(r, r, r)
|
||||
|
@ -1103,13 +1103,18 @@ static void tcg_out_qemu_ldst_i128(TCGContext *s, TCGReg data_lo, TCGReg data_hi
|
||||
}
|
||||
} else {
|
||||
/* Otherwise use a pair of LD/ST. */
|
||||
tcg_out_opc_add_d(s, TCG_REG_TMP0, h.base, h.index);
|
||||
TCGReg base = h.base;
|
||||
if (h.index != TCG_REG_ZERO) {
|
||||
base = TCG_REG_TMP0;
|
||||
tcg_out_opc_add_d(s, base, h.base, h.index);
|
||||
}
|
||||
if (is_ld) {
|
||||
tcg_out_opc_ld_d(s, data_lo, TCG_REG_TMP0, 0);
|
||||
tcg_out_opc_ld_d(s, data_hi, TCG_REG_TMP0, 8);
|
||||
tcg_debug_assert(base != data_lo);
|
||||
tcg_out_opc_ld_d(s, data_lo, base, 0);
|
||||
tcg_out_opc_ld_d(s, data_hi, base, 8);
|
||||
} else {
|
||||
tcg_out_opc_st_d(s, data_lo, TCG_REG_TMP0, 0);
|
||||
tcg_out_opc_st_d(s, data_hi, TCG_REG_TMP0, 8);
|
||||
tcg_out_opc_st_d(s, data_lo, base, 0);
|
||||
tcg_out_opc_st_d(s, data_hi, base, 8);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2049,7 +2054,7 @@ static TCGConstraintSetIndex tcg_target_op_def(TCGOpcode op)
|
||||
|
||||
case INDEX_op_qemu_ld_a32_i128:
|
||||
case INDEX_op_qemu_ld_a64_i128:
|
||||
return C_O2_I1(r, r, r);
|
||||
return C_N2_I1(r, r, r);
|
||||
|
||||
case INDEX_op_qemu_st_a32_i128:
|
||||
case INDEX_op_qemu_st_a64_i128:
|
||||
|
Loading…
Reference in New Issue
Block a user