On 4/23/25 12:09, Ben Dooks wrote:
In adding a new feature to the riscv target, it turns out the
tb_flags had already got to the 32-bit limit. Everyone other target
has been fine with uint32_t (except perhaps arm which does somethng
strange to extend tb_flags, I think).

To allow extending of tb_flags to be bigger, change the uint32_t to a tb_flags_t which a target can define to be bigger (and do this for riscv as having tb_flags_t be uint64_t somewhere is necessary to
pick out bugs in this translation).

This method of extension also stops having to go through each arch fixing field usage and anything else that may arise, and given this is currently only affecting the tcg, it can be done per target arch.

Note, target/riscv does not currently use any of the other flag bits yet. The work is done as we would like to try the big-endian riscv again and someone has already taken the last bit we where using at (target/riscv/cpu.h#L666 adding PM_SIGNEXTEND where we had BE_DATA)

Leaving aside your patch I think you can improve the density of the tbflags a bit too:

- PM_MASK_ENABLED, PM_BASE_ENABLED and AXL are unused, which gives you back 4 bits.

- VLMUL == 4 is invalid, and you can use that to get rid of VILL

- SEW reserves 3 bits, but TCG only supports 8/16/32/64; that could be one more bit if you can live with the limitation

This is already 6 bits, but for FS and VS it may be efficient enough to have just one bit (dirty vs. everything else): for all cases other than dirty, REQUIRE_FPU and require_rv* can call a helper to look at the actual MSTATUS and generate the exception if the extension is disabled; then the caller always proceeds with translation into TCG ops(*). The overhead for the DISABLED/INITIAL/CLEAN cases is minimal and it gives back 2 more bits.

Finally, in many cases it makes sense to do a full TB flush when CSRs
change. However I am not sure if this could be done for RISC-V, maybe for the CFI enabled bits?

Thanks,

Paolo

(*) that is:

static bool require_rvv(DisasContext *s)
{
    REQUIRE_EXT(s, RVV);
    if (!s->mstatus_vs_dirty) {
        gen_helper_require_rvv(tcg_env);
    }
    return true;
}

static bool require_rvf(DisasContext *s)
{
    switch (s->sew) {
    case MO_16:
        if (!s->cfg_ptr->ext_zvfh) {
            return false;
        }
        break;
    case MO_32:
        if (s->cfg_ptr->ext_zve32f) {
            return false;
        }
        break;
    case MO_64:
        if (s->cfg_ptr->ext_zve64d) {
            return false;
        }
        break;
    default:
        return false;
    }

    if (!s->mstatus_fs_dirty) {
        gen_helper_require_rvf(tcg_env);
    }
    return true;
}


Reply via email to