Re: [PATCH 0/7] RISC-V: Support version controling for ISA standard extensions and CSR

Nelson Chu
2020-04-18T11:17:25Z

Sorry for not sending these patches to Palmer :)
CC Palmer.

Thanks
Nelson

On Sat, Apr 18, 2020 at 7:08 PM Nelson Chu <nelson.chu@sifive.com> wrote:
>
> Hi binutils and gdb,
>
> I know every RISCV contirbutors all do the best to maintain the compatibility
> between different spec versions. But the specs are changed frequently, and
> sometimes it is very hard to keep the compatibility if we don't have a good
> way to deal with versioning problems. Since different ISA specs define
> different instructions, and different privilege specs define different CSR,
> both of them need the version checking and controling mechanism.
>
> For the ISA versions, you can set them by the RISCV ELF architecture attribute
> and assembler option -march, but you have to set them one by one for each
> extension. It seems not so friendly for user, so Kito Cheng proposed a good
> solution to resolve the problem. That is, support the new assembler options and
> default configure options to reduce the burdens when setting ISA versions.
> The original idea and discussion are come from the following link,
>
> https://groups.google.com/a/groups.riscv.org/forum/#!msg/sw-dev/aZhMG7NIVTk/PTZEaTWiAwAJ)
>
> === New Assembler Options ===
>
> * -misa-spec = [2p0|2p1|2p2|20190608|20191213]
> You can simply choose the ISA spec by this option, and then assembler will set
> the version for the standard extensions if you don’t set in the ELF arch
> attributes or -march option.
>
> * -mriscv-isa-version = <ISA-string>
> The syntax of <ISA-string> is same as -march option, but without rv32 or rv64
> prefix. There are two reasons that you may need this option,
>
> 1. Some versions of extensions defined in the ISA spec are not matched to the
> toolchain’s implementation. For example, V-ext is defined to version 0.7 in
> ISA spec, but we only have implementations for 0.8 and 0.9. Therefore, you
> have to use this option to choose the correct version for V-ext.
>
> 2. You want to update the version for the specific standard extensions if the
> version are not set in the ELF arch attributes and -march option.
>
> === New Default Configure Options ===
>
> * --with-arch = <ISA-string>
> The syntax of <ISA-string> is same as -march option. Assembler will check this
> if -march option and ELF arch attributes aren’t set.
>
> * --with-isa-spec = [2p0|2p1|2p2|20190608|20191213]
> The syntax is same as -misa-spec option. Assembler will check this if
> -misa-spec option isn’t set.
>
> * --with-riscv-isa-version = <ISA-string>
> The syntax of <ISA-string> is same as -mriscv-isa-version option. Assembler
> will check this if -mriscv-isa-version option isn’t set.
>
> === The Priority of these options ===
>
> * ELF arch attributes > Assembler options > Default configure options
> * For GAS options, -march > -mriscv-isa-version > -misa-spec
> * For configure options, --with-arch > --with-riscv-isa-version > --with-isa-spec
>
> === Example ===
>
> $ cat test.s
> .attribute arch, "rv32i1p9fv_zicsr"
>
> $ riscv32-unknown-elf-as -march-attr -misa-spec=2p2 -mriscv-isa-version=i2p1a2p1v0p9 test.s -o test.o
>
> $ riscv32-unknown-elf-readelf -A test.o
> Attribute Section: riscv
> File Attributes
> Tag_RISCV_arch: "rv32i1p9_f2p0_v0p9_zicsr0p0"
> ...
>
> The above example covers most cases.
>
> * For i-ext, we already set the version 1p9 in elf attribute, so -misa-spec and
> -mriscv-isa-version don't update the version to 2p0 and 2p1.
>
> * For f-ext, we don't set the version to it, so use the default version 2p0
> according to the ISA spec 2p2.
>
> * For v-ext, the default version is 0p7 according to ISA spec 2p2, but we use
> -mriscv-isa-version to update it to 0p9.
>
> * For a-ext, it isn't enabled by -march or elf attribute, so we don't update it's
> version even if -mriscv-isa-version is set.
>
> * As for the zicsr extension, it is defined in the lastest ISA spec rather than 2p2,
> so set it's version to 0p0.
>
>
> As for the privilege version, I get the related request in the following link,
> https://github.com/riscv/riscv-binutils-gdb/issues/202
>
> We also support new assembler options to choose the spec you want, and then
> assembler will generate the correct CSR address according to the chosen spec.
> If the obselete CSR name is used, then report the warning message when the
> -mcsr-check is set, and use the latest defined address for the CSR. Of course,
> you can also choose the spec by setting the orginal RISCV ELF priv attributes.
> Beside, the disassembler can show the CSR according to the chosen privilege spec
> by the new disassmebler option. However, the CSR address is showed directly if
> it is invalid for the chosen spec.
>
> === New Assembler Option ===
>
> * -mpriv-spec=[1p9|1p9p1|1p10|1p11]
> This is used to set the privileged spec’s version, and we can decide whether
> the CSR is valid or not.
>
> === New Default Configure Option ===
>
> * --with-priv-spec = [1p9|1p9p1|1p10|1p11]
> The syntax is same as -mpriv-spec option. Assembler will check this setting
> if -mpriv-spec option isn’t set.
>
> === New Disassmebler Option ===
>
> * -Mpriv-spec=[1p9|1p9p1|1p10|1p11]
> The syntax is same as -mpriv-spec option. The disassembler can show the CSR
> correctly according to the chosen privilege spec.
>
>
> Notes,
>
> 1. I'm not sure if GDB needs the above version checking, but I think the current
> modifications won't change the behavior of GDB. We still use the DECLARE_CSR
> to generate the gdb/features/riscv/[32|64]bit-csr.xml, that means we only generate
> the CSR which are valid in the latest privilege spec. Also, the objdump shows
> the CSR according to the latest privilege spec by default.
>
> 2. The default ISA spec is set to 2p2 rather than the lastest version. The reason
> is that compiler generates the ISA string with fixed 2p0 verisons only for the
> RISCV ELF architecture attributes, but not for the -march option. Therefore, we
> should update the compiler or linker to resolve this problem in the futrue patches.
>
> 3. How to extend the default versions and new ISA spec?
> You only need to update the riscv_ext_version_table which is defined in the
> opcodes/riscv-opc.c.
>
> const struct riscv_ext_version riscv_ext_version_table[] =
> {
> /* name, spec name, major, minor. */
> {"e", "20191213", 1, 9},
> {"e", "20190608", 1, 9},
> {"e", "2p2", 1, 9},
>
> {"i", "20191213", 2, 1},
> {"i", "20190608", 2, 1},
> {"i", "2p2", 2, 0},
> ...
> };
>
> 4. How to extend new privilege spec and new CSR?
>
> * include/opcode/riscv.h
> enum riscv_csr_vclass
> {
> CSR_CLASS_VNONE, /* Default value */
>
> CSR_CLASS_V1P9, /* v1.9 */
> CSR_CLASS_V1P9P1, /* v1.9.1 */
> CSR_CLASS_V1P10, /* v1.10 */
> CSR_CLASS_V1P11, /* v1.11 */
> CSR_CLASS_VDRAFT
> };
>
> * opcodes/riscv-opc.c
>
> static const struct priv_version_t priv_versions[] =
> {
> {"1p9", CSR_CLASS_V1P9},
> {"1p9p1", CSR_CLASS_V1P9P1},
> {"1p10", CSR_CLASS_V1P10},
> {"1p11", CSR_CLASS_V1P11},
>
> /* Terminate the list. */
> {NULL, 0}
> };
>
> * include/opcode/riscv-opc.h
>
> Format, DECLARE_CSR (NAME, VALUE, CLASS, DEFINE_VER, ABORT_VER)
> DECLARE_CSR_ALIAS(NAME, VALUE, CLASS, DEFINE_VER, ABORT_VER)
>
> NAME: CSR name.
> VALUE: CSR address
> CLASS: ISA dependency
> DEFINE_VER: First defined in which privilege spec.
> ABORT_VER: Aborted in which privilege spec. If the CSR is still valid in
> the lastest version, then it should be CSR_CLASS_VDRAFT.
>
> If the CSR is aborted in the latest spec, or has not only one information, then
> use DECLARE_CSR_ALIAS. Otherwise, use DECLARE_CSR.
>
> For example,
> DECLARE_CSR(ustatus, CSR_USTATUS, CSR_CLASS_I, CSR_CLASS_V1P9, CSR_CLASS_VDRAFT)
> DECLARE_CSR_ALIAS(ubadaddr, CSR_UTVAL, CSR_CLASS_I, CSR_CLASS_V1P9, CSR_CLASS_V1P10)
>
>
> Thanks
> Nelson
>