Good question!
It seems RV could have its cake and eat it too, by using the opcodes for LQ/SQ for an LX/SX instruction (which could then clearly be used where LQ/SQ would have been used on RV128). It would match intptr_t/void* (aka long/void*) in the C programming language.
To be effective I think it would then also be useful to be able to add n*(XLEN/8) to do adres computations independent of XLEN. This could be done by extending the ADD instruction with 2 extra bits to indicate the unit of what is being added
add_b rd rs1 rs2 rd<- rs1 + rs2 << 0 # This is just an alias for the add instruction and should use its opcode)
add_x rd rs1 rs2 rd<- rs1 + rs2 << log2(XLEN/8)
add_w rd rs1 rs2 rd<- rs1 + rs2 << 2
add_d rd rs1rs2 rd<- rs1 + rs2 << 3
( Perhaps for RV64/128 it is also useful to have something like
addwu_b rd rs1 rs2 rd<- rs1 + zext(rs2, 32) << 0
addwu_x rd rs1 rs2 rd<- rs1 + zext(rs2, 32) << log2(XLEN/8)
addwu_w rd rs1 rs2 rd<- rs1 + zext(rs2, 32) << 2
addwu_d rd rs1 rs2 rd<- rs1 + zext(rs2, 32) << 3
with similar adddu_[bxwd] for RV128
)
One would have to think about the most optimal Compact (C) encoding given such a scheme, but the two obvious ways would be to simply use the encoding for RV128 use the encodings for C.LQ[SP] C.SQ[SP] for LX[SP] SX[SP], but another would be to reuse the encodings for C.LD[SP] and
C.SD[SP] for a RV32/RV64 portable scheme backward compatible with RV64C that would also allow the use of C.FLD[SP]/C.FSD[SP]
[1] i.e on RV32 N(0b00) = 0, N(0b01) = 2, N(0b10) = 2 N(0b11) = 3,
on RV64 N(0b00) = 0, N(0b01) = 3 N(0b10) = 2 N(0b11) = 3,
on RV128 N(0b00) = 0, N(0b01) = 4 N(0b10) = 2 N(0b11) = 3,