KIto,
Thanks for summarizing this.
As discussed in one of the last psABI meetings, the option best
mirroring the behavior intended by the ISA specifications is "Option
3: use -misa-spec to decide what to do": unfortunately, the different
ISA specification versions define a different "expansion from string
to features" and thus we need to qualify the architecture-string
(i.e., march=) in conjunction with the specification version (i.e.
misa-spec=).
A few more comments inline below.
On Fri, 27 May 2022 at 08:19, Kito Cheng <
kito....@sifive.com> wrote:
>
> Hi all:
>
> I'd like to reach out to the community to get a better understanding
> of how we should handle ISA spec changes in the future. This topic
> that has been discussed a few years ago [1]. However, as time passed
> by, I think it is fair to raise the topic again.
>
> # What happened?
>
> Recent proposals in the profiles specification represent a change of
> the ISA specification in an incompatible way: the new specification
> drops two features from the base ISA that were there before. The two
> features that are dropped from the base ISA are now available via the
> two (new introduced) ISA extensions zicntr and zihpm. This issue was
> discovered by Jim earlier this year ([2]).
>
>
> To get an understanding of the two extensions:
>
> * zicntr covers cycle[h], time[h], instret[h] (which did not belong to
> any extension before)
> * zihpm covers hpmcounter0[h] - hpmcounter31[h] (which did not belong
> to any extension before)
>
>
> Of course, the complete picture is not that simple. The two features
> were intended to be ISA extensions in the past, but this was not done
> (see [2]).
>
>
> # What’s the problem?
>
> Currently, the Toolchain projects restrict the available features by
> parsing the march-string (provided via the -march=... option). The
> availability of features is then provided to internal code generation
> functionality (which will bail out if not-available features are
> requested) and to the provided code (via test macros like __riscv_m).
>
> When looking at zicntr (zihpm is similar) we are facing the following
> situation: the user needs to specify "zicntr" as part of the march
> string (e.g. -march=rv64i_zicntr) and the user can write test code
> that requires the __riscv_zicntr macro to be defined in order to use
> the zicntr functionality.
>
> However, code that has been written until now, will compile without
> "zicntr" as part of the march string and the code will not test for
> the availability of __riscv_zicntr.
>
> The impact is:
>
> * incompatible behavior: existing build scripts will not work with
> recent toolchains (zicntr is missing in the march string)
> * reduced support of old compilers: new code that uses the
> __riscv_zicntr macros will not work with old compilers that don't
> support zicntr, even when the functionality exists
>
> # What options do we have?
>
> ## Options 1: Ignore
>
> Use the same rules as other extensions and gate the access to the
> functionality by the march strings:
>
> - The CSRs are only available when zicntr or zihpm are enabled.
> - __riscv_zicntr/__riscv_zihpm are only defined when zicntr/zihpm are enabled.
>
> Pros: Consistent behavior with other extensions
> Cons: Incompatible change (as discussed above)
Given that these CSRs will not be widely accessed (i.e. mainly in
software running at higher privilege modes), we might get away with
breaking backward compatibility in this specific case.
However, this does probably not hold for future changes that may
impact widely visible features — so whatever solution we decide on at
this time, should be generally applicable.
> Option 2: who cares about these details
>
> Make the CSRs always available, even when zicntr or zihpm are not
> specified in the march string. Expose the test macros based on the
> availability of the extension (via march string).
>
> Pros: No compatibility issue.
> Cons: Unexpected behavior (CSRs are available although the compiler
> knows better); potentially harmful (compiler errors are expected to
> prevent unsupported code from being generated);
>
> ## Option 3: use -misa-spec to decide what to do
>
> Additionally to the flag -march=... the tools also have the flag
> -misa-spec to control the behavior of the extension parser. Currently,
> the misa-spec string can be "2.2" | "20190608" | "20191213". That flag
> is also, where would add the new profiles ("rv20" and "rv22").
>
> So for the existing misa-spec strings we would keep the current
> behavior, but for the new "rv20" and "rv22" strings, we would change
> the behavior.
From my understanding this does not entirely reflect the upstream
specification changes: any specification version that qualifies these
as explicitly gated by these new extension names will have to require
the changed behavior (i.e., not just the new profiles). Consider the
profiles as a fancy name (or a macro) expanding to a single well-known
misa-spec= and march= combination: besides using the profiles, users
will still be able to construct different misa-spec/march pairs and we
will need to process them appropriately.
> Pros: we don't try to solve a problem that is not tool-specific but
> ISA-specific; we have an option to get the old functionality back (the
> default misa-spec can be set when building a compiler using
> "--with-isa-spec=...")
> Cons: Users need to be made aware of the issue; more work with
> processing error reports from users
>
> ## Option 4: something else?
>
> The three options above are not the only existing solutions. If you
> are interested in some other solution, please share your thoughts!
>
> # References
>
> [1]
https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/aZhMG7NIVTk/m/hX2BRWsMEQAJ
> [2]
https://github.com/riscv/riscv-profiles/issues/43
Thanks,
Philipp.