On 11/10/25 10:05, Roan Richmond wrote:
+/* Zilsd extension adds load/store double for 32bit arch */
+static bool gen_store_zilsd(DisasContext *ctx, arg_sb *a)
+{
+    TCGv data_1 = tcg_temp_new();
+    TCGv data_2 = tcg_temp_new();
+    if (a->rs2 != 0) {
+        data_1 = get_gpr(ctx, a->rs2, EXT_NONE);
+        data_2 = get_gpr(ctx, a->rs2+1, EXT_NONE);
+    }
+    TCGv addr_1 = get_address(ctx, a->rs1, a->imm);
+    TCGv addr_2 = get_address(ctx, a->rs1, a->imm+4);
+
+    if (ctx->ztso) {
+        tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
+    }
+
+    tcg_gen_qemu_st_tl(data_1, addr_1, ctx->mem_idx, MO_SL);
+    tcg_gen_qemu_st_tl(data_2, addr_2, ctx->mem_idx, MO_SL);

This is wrong, because if rs2 == 0, then data_1 and data_2 are uninitialized. If you're testing properly with --enable-debug-tcg, this should trigger an assertion failure.

You wanted

    if (a->rs2 == 0) {
        data_1 = tcg_constant_tl(0);
        data_2 = data_1;
    } else {
        data_1 = get_gpr(ctx, a->rs2, EXT_NONE);
        data_2 = get_gpr(ctx, a->rs2 + 1, EXT_NONE);
    }

You're also missing the endianness indicator: mo_endian().

You really should consider combining the two halves so that you can perform one 64-bit store. While I see that the spec allows the store to be non-atomic, you still probably do not want to to allow the first half store to succeed when the second half store faults. I don't see clear language about that. Anyway, that's as simple as

    TCGv_i64 data;
    MemOp end = mo_endian(ctx);

    if (a->rs2 == 0) {
        data = tcg_constant_i64(0);
    } else {
        TCGv data_1 = get_gpr(ctx, a->rs2, EXT_NONE);
        TCGv data_2 = get_gpr(ctx, a->rs2 + 1, EXT_NONE);
        data = tcg_temp_new_i64();
        if (end == MO_LE) {
            tcg_gen_concat_tl_i64(data, data_1, data_2);
        } else {
            tcg_gen_concat_tl_i64(data, data_2, data_1);
        }
    }
    tcg_gen_qemu_st_i64(data, addr, ctx->mem_idx, MO_UQ | end);


r~

Reply via email to