[PATCH 2/7] tcg/loongarch64: Use C_N2_I1 for INDEX_op_qemu_ld_a*_i128

Richard Henderson posted 7 patches 1 year, 3 months ago
Maintainers: Richard Henderson <richard.henderson@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, WANG Xuerui <git@xen0n.name>
[PATCH 2/7] tcg/loongarch64: Use C_N2_I1 for INDEX_op_qemu_ld_a*_i128
Posted by Richard Henderson 1 year, 3 months ago
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>
---
 tcg/loongarch64/tcg-target-con-set.h |  2 +-
 tcg/loongarch64/tcg-target.c.inc     | 17 +++++++++++------
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h
index 77d62e38e7..cae6c2aad6 100644
--- a/tcg/loongarch64/tcg-target-con-set.h
+++ b/tcg/loongarch64/tcg-target-con-set.h
@@ -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)
diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
index b701df50db..40074c46b8 100644
--- a/tcg/loongarch64/tcg-target.c.inc
+++ b/tcg/loongarch64/tcg-target.c.inc
@@ -1105,13 +1105,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:
-- 
2.34.1
Re: [PATCH 2/7] tcg/loongarch64: Use C_N2_I1 for INDEX_op_qemu_ld_a*_i128
Posted by Jiajie Chen 1 year, 2 months ago
On 2023/9/17 06:01, Richard Henderson wrote:
> 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>
> ---
>   tcg/loongarch64/tcg-target-con-set.h |  2 +-
>   tcg/loongarch64/tcg-target.c.inc     | 17 +++++++++++------
>   2 files changed, 12 insertions(+), 7 deletions(-)
>
> diff --git a/tcg/loongarch64/tcg-target-con-set.h b/tcg/loongarch64/tcg-target-con-set.h
> index 77d62e38e7..cae6c2aad6 100644
> --- a/tcg/loongarch64/tcg-target-con-set.h
> +++ b/tcg/loongarch64/tcg-target-con-set.h
> @@ -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)
> diff --git a/tcg/loongarch64/tcg-target.c.inc b/tcg/loongarch64/tcg-target.c.inc
> index b701df50db..40074c46b8 100644
> --- a/tcg/loongarch64/tcg-target.c.inc
> +++ b/tcg/loongarch64/tcg-target.c.inc
> @@ -1105,13 +1105,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:


Reviewed-by: Jiajie Chen <c@jia.je>