@samitouri / QOSamiQemu / commits / 4222f75d64

target/riscv: Make LQ and SQ use 128-bit ld/st

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> Message-ID: <20260318103122.97244-4-philmd@linaro.org> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Frédéric Pétrot committed Mar 18, 2026 at 11:31 UTC 4222f75d6443f5b8407dded40a7a83a5a8d9f8bd
1 file changed +24 -8
target/riscv/insn_trans/trans_rvi.c.inc
+24 -8
@@ -377,6 +377,9 @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
377 TCGv destl = dest_gpr(ctx, a->rd);
378 TCGv desth = dest_gprh(ctx, a->rd);
379 TCGv addrl = tcg_temp_new();
380 + TCGv_i128 t16 = tcg_temp_new_i128();
381 + TCGv_i64 tl = tcg_temp_new_i64();
382 + TCGv_i64 th = tcg_temp_new_i64();
383
384 tcg_gen_addi_tl(addrl, src1l, a->imm);
385
@@ -388,10 +391,14 @@ static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
391 tcg_gen_movi_tl(desth, 0);
392 }
393 } else {
391 - /* assume little-endian memory access for now */
392 - tcg_gen_qemu_ld_tl(destl, addrl, ctx->mem_idx, MO_TEUQ);
393 - tcg_gen_addi_tl(addrl, addrl, 8);
394 - tcg_gen_qemu_ld_tl(desth, addrl, ctx->mem_idx, MO_TEUQ);
394 + tcg_gen_qemu_ld_i128(t16, addrl, ctx->mem_idx, memop);
395 + if (mo_endian(ctx) == MO_LE) {
396 + tcg_gen_extr_i128_i64(tl, th, t16);
397 + } else {
398 + tcg_gen_extr_i128_i64(th, tl, t16);
399 + }
400 + tcg_gen_trunc_i64_tl(destl, tl);
401 + tcg_gen_trunc_i64_tl(desth, th);
402 }
403
404 gen_set_gpr128(ctx, a->rd, destl, desth);
@@ -488,16 +495,25 @@ static bool gen_store_i128(DisasContext *ctx, arg_sb *a, MemOp memop)
495 TCGv src2l = get_gpr(ctx, a->rs2, EXT_NONE);
496 TCGv src2h = get_gprh(ctx, a->rs2);
497 TCGv addrl = tcg_temp_new();
498 + TCGv_i128 t16 = tcg_temp_new_i128();
499 + TCGv_i64 tl = tcg_temp_new_i64();
500 + TCGv_i64 th = tcg_temp_new_i64();
501
502 tcg_gen_addi_tl(addrl, src1l, a->imm);
503
504 if ((memop & MO_SIZE) <= MO_64) {
505 tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, memop);
506 } else {
497 - /* little-endian memory access assumed for now */
498 - tcg_gen_qemu_st_tl(src2l, addrl, ctx->mem_idx, MO_TEUQ);
499 - tcg_gen_addi_tl(addrl, addrl, 8);
500 - tcg_gen_qemu_st_tl(src2h, addrl, ctx->mem_idx, MO_TEUQ);
507 +
508 + tcg_gen_ext_tl_i64(tl, src2l);
509 + tcg_gen_ext_tl_i64(th, src2h);
510 +
511 + if (mo_endian(ctx) == MO_LE) {
512 + tcg_gen_concat_i64_i128(t16, tl, th);
513 + } else {
514 + tcg_gen_concat_i64_i128(t16, th, tl);
515 + }
516 + tcg_gen_qemu_st_i128(t16, addrl, ctx->mem_idx, memop);
517 }
518 return true;
519 }