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);
+ }
+}