config-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] Add "riscv" as an alias for "riscv32"


From: John Ericson
Subject: Re: [PATCH] Add "riscv" as an alias for "riscv32"
Date: Thu, 21 Jun 2018 20:28:50 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.2.1

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...



reply via email to

[Prev in Thread] Current Thread [Next in Thread]