[PATCH-for-11.1 03/16] target/riscv: Make LQ and SQ use 128-bit ld/st

Philippe Mathieu-Daudé posted 16 patches 2 weeks, 5 days ago
Maintainers: Laurent Vivier <laurent@vivier.eu>, Pierrick Bouvier <pierrick.bouvier@linaro.org>, Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Weiwei Li <liwei1518@gmail.com>, Daniel Henrique Barboza <daniel.barboza@oss.qualcomm.com>, Liu Zhiwei <zhiwei_liu@linux.alibaba.com>, Chao Liu <chao.liu.zevorn@gmail.com>, Warner Losh <imp@bsdimp.com>, Kyle Evans <kevans@freebsd.org>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, Paolo Bonzini <pbonzini@redhat.com>, Vijai Kumar K <vijai@behindbytes.com>, "Edgar E. Iglesias" <edgar.iglesias@gmail.com>, Peter Maydell <peter.maydell@linaro.org>
[PATCH-for-11.1 03/16] target/riscv: Make LQ and SQ use 128-bit ld/st
Posted by Philippe Mathieu-Daudé 2 weeks, 5 days ago
From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>

The lq and sq helpers for the experimental rv128 architecture
currently use direct memory accesses.
Replace these direct accesses with the standard
tcg_gen_qemu_{ld,st}_i128 TCG helpers that handle endianness
issues.

Reported-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
Message-ID: <20260101181442.2489496-2-frederic.petrot@univ-grenoble-alpes.fr>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
---
 target/riscv/insn_trans/trans_rvi.c.inc | 32 ++++++++++++++++++-------
 1 file changed, 24 insertions(+), 8 deletions(-)

diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
index 54b9b4f2413..2c82ae41a77 100644
--- a/target/riscv/insn_trans/trans_rvi.c.inc
+++ b/target/riscv/insn_trans/trans_rvi.c.inc
@@ -377,6 +377,9 @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
     TCGv destl = dest_gpr(ctx, a->rd);
     TCGv desth = dest_gprh(ctx, a->rd);
     TCGv addrl = tcg_temp_new();
+    TCGv_i128 t16 = tcg_temp_new_i128();
+    TCGv_i64 tl = tcg_temp_new_i64();
+    TCGv_i64 th = tcg_temp_new_i64();
 
     tcg_gen_addi_tl(addrl, src1l, a->imm);
 
@@ -388,10 +391,14 @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
             tcg_gen_movi_tl(desth, 0);
         }
     } else {
-        /* assume little-endian memory access for now */
-        tcg_gen_qemu_ld_tl(destl, addrl, ctx->mem_idx, MO_TEUQ);
-        tcg_gen_addi_tl(addrl, addrl, 8);
-        tcg_gen_qemu_ld_tl(desth, addrl, ctx->mem_idx, MO_TEUQ);
+        tcg_gen_qemu_ld_i128(t16, addrl, ctx->mem_idx, memop);
+        if (mo_endian(ctx) == MO_LE) {
+            tcg_gen_extr_i128_i64(tl, th, t16);
+        } else {
+            tcg_gen_extr_i128_i64(th, tl, t16);
+        }
+        tcg_gen_trunc_i64_tl(destl, tl);
+        tcg_gen_trunc_i64_tl(desth, th);
     }
 
     gen_set_gpr128(ctx, a->rd, destl, desth);
@@ -488,16 +495,25 @@ static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop)
     TCGv src2l = get_gpr(ctx, a->rs2, EXT_NONE);
     TCGv src2h = get_gprh(ctx, a->rs2);
     TCGv addrl = tcg_temp_new();
+    TCGv_i128 t16 = tcg_temp_new_i128();
+    TCGv_i64 tl = tcg_temp_new_i64();
+    TCGv_i64 th = tcg_temp_new_i64();
 
     tcg_gen_addi_tl(addrl, src1l, a->imm);
 
     if ((memop & MO_SIZE) <= MO_64) {
         tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, memop);
     } else {
-        /* little-endian memory access assumed for now */
-        tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, MO_TEUQ);
-        tcg_gen_addi_tl(addrl, addrl, 8);
-        tcg_gen_qemu_st_tl(src2h, addrl, ctx->mem_idx, MO_TEUQ);
+
+        tcg_gen_ext_tl_i64(tl, src2l);
+        tcg_gen_ext_tl_i64(th, src2h);
+
+        if (mo_endian(ctx) == MO_LE) {
+            tcg_gen_concat_i64_i128(t16, tl, th);
+        } else {
+            tcg_gen_concat_i64_i128(t16, th, tl);
+        }
+        tcg_gen_qemu_st_i128(t16, addrl, ctx->mem_idx, memop);
     }
     return true;
 }
-- 
2.53.0


Re: [PATCH-for-11.1 03/16] target/riscv: Make LQ and SQ use 128-bit ld/st
Posted by Alistair Francis 1 week, 4 days ago
On Wed, Mar 18, 2026 at 8:34 PM Philippe Mathieu-Daudé
<philmd@linaro.org> wrote:
>
> From: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
>
> The lq and sq helpers for the experimental rv128 architecture
> currently use direct memory accesses.
> Replace these direct accesses with the standard
> tcg_gen_qemu_{ld,st}_i128 TCG helpers that handle endianness
> issues.
>
> Reported-by: Philippe Mathieu-Daudé <philmd@linaro.org>
> Suggested-by: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Frédéric Pétrot <frederic.petrot@univ-grenoble-alpes.fr>
> Message-ID: <20260101181442.2489496-2-frederic.petrot@univ-grenoble-alpes.fr>
> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Reviewed-by: Alistair Francis <alistair.francis@wdc.com>

Alistair

> ---
>  target/riscv/insn_trans/trans_rvi.c.inc | 32 ++++++++++++++++++-------
>  1 file changed, 24 insertions(+), 8 deletions(-)
>
> diff --git a/target/riscv/insn_trans/trans_rvi.c.inc b/target/riscv/insn_trans/trans_rvi.c.inc
> index 54b9b4f2413..2c82ae41a77 100644
> --- a/target/riscv/insn_trans/trans_rvi.c.inc
> +++ b/target/riscv/insn_trans/trans_rvi.c.inc
> @@ -377,6 +377,9 @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
>      TCGv destl = dest_gpr(ctx, a->rd);
>      TCGv desth = dest_gprh(ctx, a->rd);
>      TCGv addrl = tcg_temp_new();
> +    TCGv_i128 t16 = tcg_temp_new_i128();
> +    TCGv_i64 tl = tcg_temp_new_i64();
> +    TCGv_i64 th = tcg_temp_new_i64();
>
>      tcg_gen_addi_tl(addrl, src1l, a->imm);
>
> @@ -388,10 +391,14 @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
>              tcg_gen_movi_tl(desth, 0);
>          }
>      } else {
> -        /* assume little-endian memory access for now */
> -        tcg_gen_qemu_ld_tl(destl, addrl, ctx->mem_idx, MO_TEUQ);
> -        tcg_gen_addi_tl(addrl, addrl, 8);
> -        tcg_gen_qemu_ld_tl(desth, addrl, ctx->mem_idx, MO_TEUQ);
> +        tcg_gen_qemu_ld_i128(t16, addrl, ctx->mem_idx, memop);
> +        if (mo_endian(ctx) == MO_LE) {
> +            tcg_gen_extr_i128_i64(tl, th, t16);
> +        } else {
> +            tcg_gen_extr_i128_i64(th, tl, t16);
> +        }
> +        tcg_gen_trunc_i64_tl(destl, tl);
> +        tcg_gen_trunc_i64_tl(desth, th);
>      }
>
>      gen_set_gpr128(ctx, a->rd, destl, desth);
> @@ -488,16 +495,25 @@ static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop)
>      TCGv src2l = get_gpr(ctx, a->rs2, EXT_NONE);
>      TCGv src2h = get_gprh(ctx, a->rs2);
>      TCGv addrl = tcg_temp_new();
> +    TCGv_i128 t16 = tcg_temp_new_i128();
> +    TCGv_i64 tl = tcg_temp_new_i64();
> +    TCGv_i64 th = tcg_temp_new_i64();
>
>      tcg_gen_addi_tl(addrl, src1l, a->imm);
>
>      if ((memop & MO_SIZE) <= MO_64) {
>          tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, memop);
>      } else {
> -        /* little-endian memory access assumed for now */
> -        tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, MO_TEUQ);
> -        tcg_gen_addi_tl(addrl, addrl, 8);
> -        tcg_gen_qemu_st_tl(src2h, addrl, ctx->mem_idx, MO_TEUQ);
> +
> +        tcg_gen_ext_tl_i64(tl, src2l);
> +        tcg_gen_ext_tl_i64(th, src2h);
> +
> +        if (mo_endian(ctx) == MO_LE) {
> +            tcg_gen_concat_i64_i128(t16, tl, th);
> +        } else {
> +            tcg_gen_concat_i64_i128(t16, th, tl);
> +        }
> +        tcg_gen_qemu_st_i128(t16, addrl, ctx->mem_idx, memop);
>      }
>      return true;
>  }
> --
> 2.53.0
>
>