That all sounds great to me---definitely not too much detail for my
curiosity at least :).
> We originally kicked around the idea of calling the targets
"riscv32imac-*", but when we ended up with the mostly orthogonal -mabi
and -mtune arguments we decided to give up as a tuple like
"riscv32imacilp32rocket-*" seemed just too insane to deal with.
I'm glad to you all at least pondered it. I agree at the finest level of
detail the idea of a single string becomes just too unwieldy. [As an
aside, it's for this reason I'd long hoped all the major compilers could
collaborate on a standard for JSON representations of targets.
Structured descriptions have at least been pursued by Rustc, Meson, and
NixOS.]
> The base ISAs are
* rv32e: 16 integer registers, each of 32 bits
* rv32i: 32 integer registers, each of 32 bits
* rv64i: 32 integer registers, each of 64 bits
I don't know that the official policy is on breaking changes. But what
if the target config had to be one of those three (i.e. `rv32e-*`
`rv32i-*` and `rv64i-*`)? Combining rv32e and rv32i under `riscv32-*`
seems arbitrary and in ignorance of the spec. A 4th `riscv-` form would
be allowed just for tools. `riscv64-` and `riscv32-` would no longer be
allowed.
> Toolchains will default to one {-march, -mabi, -mtune} value, which
is a compile-time setting.
Yes nothing can be done in GNU config to change this, but maybe GCC and
Binutils can someday be persuaded to allow no default after.
> As a result we just tell users that they should always fully specify
{-march, -mabi, -mtune} when cross compiling, and that build systems
should just ignore the tuple as it doesn't really mean anything.
That is understandable, if not ideal, advice to today. But with
`riscv{,32e,32i,64i}-` available the tools can be more aggressive in
deciding whether the tool supports the target. (For example on NixOS,
the distro I work on, the compiler will be wrapped with a shell script
providing the libc etc so all hundreds of combinations indeed are
feasible without multi-lib or extra builds, but the config must always
be respected or the libraries are missing.) Also, This could then be
consistent with LLVM that I imagine might at least warn if the `-march`
and `-target` do not agree.
> I'd like to keep the behavior for native compilers where the default
target is the native host, as otherwise we'll end up with unnecessary
arguments floating around everywhere.
Yes unprefixed native compilers should do that for consistency. But if
one passes `--target riscv-*` on riscv (the "identity" cross compiler),
I imagine the default might still be based on the machine, and so
non-deterministic with respect to the target config, which is the
slightly more confusing thing to fix if GCC can be taught not to have
defaults.
John
On 06/21/18 15:11, Palmer Dabbelt wrote:
I like the idea of forcing an explicit target declaration for our
cross compilers -- it's stronger than even just "riscv-*" needs it, as
"riscv32-*" isn't sufficient to determine the target. This behavior
manifests because the RISC-V ISA is defined as a set of base ISAs
along with a set of extensions. The base ISAs are
* rv32e: 16 integer registers, each of 32 bits
* rv32i: 32 integer registers, each of 32 bits
* rv64i: 32 integer registers, each of 64 bits
and the currently defined user-mode extensions are
* m: Adds multiplication and division instructions
* a: Adds atomic operations (lr/sc and various AMOs)
* f: Adds 32 single precision registers along with single-precision
instructions
* d: Extends the F register set to double precision and adds the
corresponding instructions.
* c: Adds compressed versions of many common instructions
We express this to the compiler using the "-march" argument, via a
string that looks something like "-march=rv64imafdc", which controls
the instructions available for code generation. We also have an ABI
selection argument, -mabi, which allows users to select the calling
convention used (this exists to allow things like Intel's x32 and
ARM's softfloat/softfp/hardfp). There's a third argument, -mtune,
that controls how to tune for a particular microarchitecture.
Toolchains will default to one {-march, -mabi, -mtune} value, which is
a compile-time setting. binutils and GCC always support code
generation for all legal {-march, -mabi, -mtune} settings, but a
multilib toolchain is necessary to have multiple libc/libgccs (and
even then we limit this to the commonly used settings, as otherwise
there would be hundreds). The current scheme is that "riscv32-*"
defaults to some rv32i-based target and "riscv64-*" defaults to some
rv64i-based target, but nothing tells you which one. The currently
appearing "riscv-*" binaries might default to rv32i or rv64i depending
on who produced it.
We originally kicked around the idea of calling the targets
"riscv32imac-*", but when we ended up with the mostly orthogonal -mabi
and -mtune arguments we decided to give up as a tuple like
"riscv32imacilp32rocket-*" seemed just too insane to deal with. As a
result we just tell users that they should always fully specify
{-march, -mabi, -mtune} when cross compiling, and that build systems
should just ignore the tuple as it doesn't really mean anything.
I'd like to keep the behavior for native compilers where the default
target is the native host, as otherwise we'll end up with unnecessary
arguments floating around everywhere.
I've written a blog post about our target compiler options if you're
interested
https://www.sifive.com/blog/2017/08/14/all-aboard-part-1-compiler-args/
Sorry if that's a bit too much detail...
_______________________________________________
config-patches mailing list
config-patches@gnu.org
https://lists.gnu.org/mailman/listinfo/config-patches