Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework riscv -march and -mabi detection #796

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

dramforever
Copy link

Currently all the riscv*gc targets use the 'd' double-float ABI, and
soft-float otherwise. There's no need to detect the operating system
type. Fixes #795.

I'm not sure how correct this is. I've checked all the targets on version
1.69.0-nightly (ef934d9b6 2023-02-08) with this script:

rustc --print target-list |
  grep riscv |
  while IFS= read target; do
    rustc --target "$target" --print target-spec-json -Z unstable-options |
      jq --arg name "$target" -r '"\(.["llvm-abiname"]) \($name)"'
  done

Which gives:

ilp32d riscv32gc-unknown-linux-gnu
ilp32d riscv32gc-unknown-linux-musl
null riscv32i-unknown-none-elf
null riscv32im-unknown-none-elf
null riscv32imac-unknown-none-elf
null riscv32imac-unknown-xous-elf
null riscv32imc-esp-espidf
null riscv32imc-unknown-none-elf
lp64d riscv64gc-unknown-freebsd
lp64d riscv64gc-unknown-linux-gnu
lp64d riscv64gc-unknown-linux-musl
lp64d riscv64gc-unknown-none-elf
lp64d riscv64gc-unknown-openbsd
null riscv64imac-unknown-none-elf

Also I'm not sure whether to add tests or not. Please advise on this.

src/lib.rs Outdated

// If riscv32gc-* or riscv64gc-* then double-float ABI,
// otherwise use soft-float ABI.
let float_abi = if arch.contains("g") { "d" } else { "" };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks fragile to me, maybe we could use arch.ends_with("gc") or contains("gc") at least.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My reasoning is that g means imafd_zifencei_zicsr, so it implies d for double, which is required for double float ABI. Currently it seems (see table in top post) that rustc does use lp64d/ilp32d for all targets with double. Maybe I can change the code to detect d or g and/or change the comment to reflect this reasoning better?

I guess I'll also change it so that it handles e.g. riscv64imac_zsomething with a multi-letter extension tha happens to contain g. Not sure if something other than an ISA/-march string appears here though tbh.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the RISC-V Unprivileged Specification RISC-V ISA can be decided from ISA string, which indicates that if it has D inside, the target must support double length floating points; and G means that it has IMAFD and Zifencei (F indicates Zicsr). Using C here would not cover this case correctly, as that C doesn't imply G or D.

It is possible to have an RVD implementation without RVC, for example disabling C instruction set on RV64GC platform (which is sometimes common on embedded SoC or developing new SoCs); detecting GC for D will not be correct in those cases.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added a bunch of comments explaining the logic, and also updated the detection logic to handle the possible future existence of multi-letter extensions, so it won't get confused by e.g. riscv64imac_zsomething containing a g.

@dramforever dramforever force-pushed the riscv-abi-arch-fix branch 5 times, most recently from 989026d to 23303fc Compare March 19, 2023 06:40
Instead of adding cases for all the operating systems, Use target
architecture directly as ISA string, replacing "riscv" with "rv", and
detect floating point ABI based on support for the D and F extensions.

Fixes rust-lang#795
@dramforever
Copy link
Author

dramforever commented Apr 8, 2023

Additional justification for inferring the ABI: https://github.com/riscv-non-isa/riscv-toolchain-conventions#specifying-the-target-isa-with--march

A target -march which includes floating point instructions implies a hardfloat calling convention, but can be overridden using the -mabi flag

Since the Rust target implies -march, it makes sense to also infer -mabi from it.

I can add a comment linking to it, if the maintainers are okay with this logic in general.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ABI mismatch for riscv64gc-unknown-none-elf
3 participants