Skip to content

Commit

Permalink
Define -march string
Browse files Browse the repository at this point in the history
This is essentially a collection of all recent
change requests for the -march string:

* Relax the ISA string order ([1])
* Add custom extensions ([2])
* Add profiles support ([3])

Most of this patch is based on proposals from Kito Cheng <kito.cheng@gmail.com>
(see linked resources below).

[1] #14
[2] #1
[3] https://lists.riscv.org/g/sig-toolchains/message/379
[4] #11

Signed-off-by: Christoph Müllner <christoph.muellner@vrull.eu>
  • Loading branch information
cmuellner committed Dec 1, 2022
1 parent ce6452b commit 5570a72
Showing 1 changed file with 136 additions and 26 deletions.
162 changes: 136 additions & 26 deletions README.mkd
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,144 @@ Manual](https://github.com/riscv-non-isa/riscv-asm-manual/blob/master/riscv-asm.
* [GCC RISC-V option
documentation](https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Options.html)

## Specifying the target ISA with -march

The compiler and assembler both accept the `-march` flag to specify the target
ISA, e.g. `rv32imafd`. The abbreviation `g` can be used to represent either
`IMAFD` (when targeting RISC-V ISA specification version 2.2 or earlier) or
`IMAFD_Zicsr_Zifencei` (version 20190608 or later) base and extensions,
e.g. `-march=rv64g`. A target `-march` which includes floating point
instructions implies a hardfloat calling convention, but can be overridden
using the `-mabi` flag (see the next section).

The ISA subset naming conventions are described in Chapter 27 of the RISC-V
user-level ISA specification. However, tools do not currently follow this
specification (input is case sensitive, ...).

If the 'C' (compressed) instruction set extension is targeted, the compiler
## Specifying the target ISA with `-march` and `-misa-spec`

The compiler and assembler both accept the `-march` flag to specify the target
ISA. Additionally, the `-misa-spec` flag allows specifying the ISA specification
release, which can have a subtle difference on how the string provided to the
`-march` flag is interpreted.

The `-march` string can be defined using one of the following formats:
1) using the ISA-string-based format, or
2) using the profile-based format.

Both formats allow specifying a list of extensions that form an additive set.

### ISA-string-based format

The ISA-string-based format looks similar to ISA naming strings as specified
in the ISA Extension Naming Conventions chapter of the RISC-V ISA
specification.

A valid `-march` string in the ISA-string-based format must follow these rules:

* All characters of the string must be lowercase.
* The first part of the string must be `rv32`, `rv64`, or `rv128` followed by
the base integer ISA (`i`, or `e`). As `g` implies `i`, this letter can
also be used.
* The next part consists of single-letter and multi-letter ISA extensions,
which may be in non-canonical order.
* Single-letter ISA extensions may be separated from other single-letter extensions
by an underscore (`_`).
* Multi-letter ISA extensions must be separated from other extensions
by an underscore (`_`).
* Versioning of extensions follows the ISA naming string rules (e.g. `zba1p0`).
Single-letter extensions with versioning are still considered single-letter
extensions (`m1p0` is considered a single-letter extension).
* Version separator(`p`) has a higher priority than a trailing `p` in the
extension name. E.g. `zba1p` will be interpreted as `zba` version 1.0 and
not as `zba1p`.

Examples:

* `rv32imac`: Valid `-march` string.
* `rv64gc`: Valid ISA string.
* `rv32ima_zicsr`: Valid `-march` string.
* `rv32i2p1m2p0a2p1f2p2d2p2c_zicsr_zifencei`: Valid `-march` string.
* `rv64gc_zba_zbb_zbc1p0`: Valid `-march` string.
* `rv64gc_xtheadba`: Valid `-march` string.
* `rv32i_zicsr_mafd`: Valid `-march` string.
* `rv32i_mafd_zicsr`: Valid `-march` string.
* `rv32i_m_a_f_d_zicsr`: Valid `-march` string.
* `rv32i_mafdzicsr`: Invalid because `mafdzicsr` does not separate the multi-letter extension `Zicsr`.
* `rv64gc_Zicsr`: Invalid because of the uppercase character.
* `rv32mai`: Invalid because base ISA does not follow `rv32`.
* `rv32i_zicsrzifencei`: Invalid because multi-letter extensions need to be
separated by an underscore (`zicsr` and `zifencei` are existing individual
extensions).

NOTE: A RISC-V ISA extension might depend on other ISA extensions.
This dependencies are honored by the `-march` string.
E.g. `D` implies `F` and does not need to be listed explicitly.

NOTE: The ISA-string-based format is a user-friendly format,
that is different from the machine-friendly format in the ELF
tag `Tag_RISCV_arch`.

#### Interpretation versioning with `-misa-spec`

The interpretation of the string provided to the `-march` flag
in ISA-string-based format is versioned using the `-misa-spec` flag.
The `-misa-spec` flag is incompatible with a string provided
to the `-march` flag in the profile-based format.

Possible versions are:

* `2.2`
* `20190608`
* `20191213`

Additional versions might appear in the future if a change of
the interpretation is required.

The following interpretation differences exist:

* The expansion of `g` with versions before `20190608` is `imafd`.
The expansion of `g` with version `20190609` or later is
`imafd_zicsr_zifencei`.

Examples:

* `-march=rv64gc -misa-spec=20191213` enables RV64I and the extensions
`mafdc` as well as `zicsr` and `zifencei`.
* `-march=rv64gc -misa-spec=rva22` is invalid (unknown ISA version).

NOTE: The RISC-V specification is intended to be backward and
forward-compatible. However, such a goal is usually hard to achieve and fixes
for mistakes in specifications or misinterpretation of specifications
may require differences in how the `-march` string is interpreted.
The required changes are subtle and irrelevant to most users.
However, a mechanism to enable old behavior (even if considered wrong)
is considered a helpful solution for users that depend on this behavior.

### Profile-based format

The profiles-string-based format has the following form
`-march=<profile-name>[+<option-ext>]+`.

Profile names are lowercase strings of the profile name (e.g. `rva22u64`).
It is possible to add additional extensions using the `+` character.

The effect of specifying a profile is that all mandatory extensions
of that profile will be enabled. The list of mandatory extensions
of a profile can be found in the RISC-V profiles specification.

The profiles-string-based format is implicitly versioned
by the profile's prefix (e.g. "rva22"), therefore a change in the
interpretation (if necessary) can be introduced by adding support
for a new profile version. Therefore, the profiles-string-based format
is not compatible with the versioning flag `-misa-spec`.

Examples:

* `rva22u64`: Valid `-march` string.
* `rva22u64+v` Valid `-march` string.
* `rva22u64+xtheadba`: Valid `-march` string.
* `rva22u64+xventanacondopts1p0`: Valid -march string.
* `RVA22U64`: Invalid because the string must not contain uppercase characters.
* `rva22u64+zfinx` is not valid because Zfinx is incompatible with RVA22U64.
* `-march=rva22u64 -misa-spec=2.2` is not valid because the `-misa-spec`
flag is not compatible with the profile-based format.

### Implicit effects of the `-march` string

A target `-march` string, which includes floating point instructions, implies a
hardfloat calling convention, but can be overridden using the `-mabi` flag
(see the next section).

If the `c` (compressed) instruction set extension is targeted, the compiler
will generate compressed instructions where possible.

### Issues for consideration
* Whether `riscv32` and `riscv64` should be accepted as synonyms for `rv32`
and `rv64`.
* Whether the `-march` string should be parsed case insensitively.
* Exposing the ability to specify version numbers for a target extension.
* Specifying non-standard extensions. The ISA specification suggests naming
such as `rv32gXfirstext_Xsecondext`. In GCC or Clang it would be more
conventional to give a string such as `rv32g+firstext+secondext`.
* Whether ordering should be enforced on the ISA string (e.g. currently
`rv32imafd` is accepted by GCC but `rv32iamfd` is not).

## Specifying the target ABI with -mabi

RISC-V compilers support the following ABIs, which can be specified using
Expand Down

0 comments on commit 5570a72

Please sign in to comment.