On 10/10/25 17:05, Philippe Mathieu-Daudé wrote:
Hi Frédéric,

(old patch merged as commit a2f827ff4f44)

On 6/1/22 22:00, Frédéric Pétrot wrote:
Get function to retrieve the 64 top bits of a register, stored in the gprh field of the cpu state. Set function that writes the 128-bit value at once.
The access to the gprh field can not be protected at compile time to make
sure it is accessed only in the 128-bit version of the processor because we
have no way to indicate that the misa_mxl_max field is const.

The 128-bit ISA adds ldu, lq and sq. We provide support for these
instructions. Note that (a) we compute only 64-bit addresses to actually
access memory, cowardly utilizing the existing address translation mechanism
of QEMU, and (b) we assume for now little-endian memory accesses.

Signed-off-by: Frédéric Pétrot <[email protected]>
Co-authored-by: Fabien Portas <[email protected]>
Reviewed-by: Alistair Francis <[email protected]>
---
  target/riscv/insn16.decode              |  27 ++++++-
  target/riscv/insn32.decode              |   5 ++
  target/riscv/translate.c                |  41 ++++++++++
  target/riscv/insn_trans/trans_rvi.c.inc | 100 ++++++++++++++++++++++--
  4 files changed, 163 insertions(+), 10 deletions(-)


+/* Compute only 64-bit addresses to use the address translation mechanism */
+static bool gen_load_i128(DisasContext *ctx, arg_lb *a, MemOp memop)
+{
+    TCGv src1l = get_gpr(ctx, a->rs1, EXT_NONE);
+    TCGv destl = dest_gpr(ctx, a->rd);
+    TCGv desth = dest_gprh(ctx, a->rd);
+    TCGv addrl = tcg_temp_new();
+
+    tcg_gen_addi_tl(addrl, src1l, a->imm);
+
+    if ((memop & MO_SIZE) <= MO_64) {
+        tcg_gen_qemu_ld_tl(destl, addrl, ctx->mem_idx, memop);
+        if (memop & MO_SIGN) {
+            tcg_gen_sari_tl(desth, destl, 63);
+        } else {
+            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);

I am confused by this "assume little-endian access" comment, since
you set the MO_TE flag (target endianness). I suppose you added the
comment since the @memop argument is ignored in this code path.
Maybe you want 'MO_LEUQ' here instead, to select little endianness?

Proposed fix:
https://lore.kernel.org/qemu-riscv/[email protected]/


+    }
+
+    gen_set_gpr128(ctx, a->rd, destl, desth);
+
+    tcg_temp_free(addrl);
+    return true;
+}
+
+static bool gen_load(DisasContext *ctx, arg_lb *a, MemOp memop)
+{
+    if (get_xl(ctx) == MXL_RV128) {
+        return gen_load_i128(ctx, a, memop);
+    } else {
+        return gen_load_tl(ctx, a, memop);
+    }
+}


Reply via email to