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

[RISCV] Use lld as the default linker; Enable C extension; Add riscv32imc-unknown-none-elf target #53822

Merged
merged 4 commits into from
Sep 1, 2018

Conversation

dvc94ch
Copy link
Contributor

@dvc94ch dvc94ch commented Aug 30, 2018

The riscv32imc-unknown-none-elf target is intended for soft cores.

The riscv32imc target is supported by the following popular soft cores:

picorv32: https://github.com/cliffordwolf/picorv32
vexriscv: https://github.com/SpinalHDL/VexRiscv
pulp riscy: https://github.com/pulp-platform/riscv
pulp zero-riscy: https://github.com/pulp-platform/zero-riscy

@rust-highfive
Copy link
Collaborator

r? @varkor

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 30, 2018
@japaric
Copy link
Member

japaric commented Aug 30, 2018

r? @japaric

@rust-highfive rust-highfive assigned japaric and unassigned varkor Aug 30, 2018
Copy link
Member

@japaric japaric left a comment

Choose a reason for hiding this comment

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

Just to confirm these IMC targets do not even support atomic loads and stores? Or do they support atomic loads and stores but not CAS operations?

target_env: String::new(),
target_vendor: "unknown".to_string(),
arch: "riscv32".to_string(),
linker_flavor: LinkerFlavor::Ld,
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be LinkerFlavor::Lld(LldFlavor::Ld)?

panic_strategy: PanicStrategy::Abort,
relocation_model: "static".to_string(),
emit_debug_gdb_scripts: false,
abi_blacklist: vec![
Copy link
Member

Choose a reason for hiding this comment

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

if this is the same list as the one used in the IMAC target could you refactor it into a function? See arm_base::abi_blacklist.

@@ -25,11 +25,11 @@ pub fn target() -> TargetResult {
linker_flavor: LinkerFlavor::Ld,
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't this be LinkerFlavor::Lld(LldFlavor::Ld)?

cpu: "generic-rv32".to_string(),
max_atomic_width: Some(32),
atomic_cas: false, // incomplete +a extension
features: "+m,+a".to_string(), // disable +c extension
features: "+m,+a,+c".to_string(),
Copy link
Member

Choose a reason for hiding this comment

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

🎉

@@ -25,11 +25,11 @@ pub fn target() -> TargetResult {
linker_flavor: LinkerFlavor::Ld,

options: TargetOptions {
linker: Some("riscv32-unknown-elf-ld".to_string()),
linker: Some("rust-lld".to_string()),
cpu: "generic-rv32".to_string(),
max_atomic_width: Some(32),
atomic_cas: false, // incomplete +a extension
Copy link
Member

Choose a reason for hiding this comment

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

Just checking: this hasn't been fixed yet?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope, a few commits have happened but nothing that "interesting".

@dvc94ch
Copy link
Contributor Author

dvc94ch commented Aug 30, 2018

Just to confirm these IMC targets do not even support atomic loads and stores? Or do they support atomic loads and stores but not CAS operations?

Ah yes, loads and stores up to pointer width should be atomic.

@japaric
Copy link
Member

japaric commented Aug 30, 2018

Ah yes, loads and stores up to pointer width should be atomic.

LLVM says otherwise:

#![no_std]

use core::sync::atomic::{Ordering, AtomicUsize};

#[no_mangle]
pub fn foo(x: &AtomicUsize) -> usize {
    x.load(Ordering::SeqCst)
}

IMAC

$ $(rustc +nightly --print sysroot)/bin/llvm-objdump -d target/riscv32imac-unknown-none-elf/release/libfoo.rlib

target/riscv32imac-unknown-none-elf/release/libfoo.rlib(foo-5c3d4a3cd43899d6.foo.axz7xdhy-cgu.0.rcgu.o): file format ELF32-riscv

Disassembly of section .text.foo:
foo:
       0:       0f 00 30 03     fence   rw, rw
       4:       08 41   lw      a0, 0(a0)
       6:       0f 00 30 02     fence   r, rw
       a:       82 80   ret

$ $(rustc +nightly --print sysroot)/bin/llvm-nm target/riscv32imac-unknown-none-elf/release/libfoo.rlib

foo-5c3d4a3cd43899d6.foo.axz7xdhy-cgu.0.rcgu.o:
00000000 T foo

IMC

$ $(rustc +nightly --print sysroot)/bin/llvm-objdump -d target/riscv32imc-unknown-none-elf/release/libfoo.rlib
target/riscv32imc-unknown-none-elf/release/libfoo.rlib(foo-5c3d4a3cd43899d6.foo.axz7xdhy-cgu.0.rcgu.o): file format ELF32-riscv

Disassembly of section .text.foo:
foo:
       0:       41 11   addi    sp, sp, -16
       2:       06 c6   sw      ra, 12(sp)
       4:       95 45   addi    a1, zero, 5
       6:       97 00 00 00     auipc   ra, 0
       a:       e7 80 00 00     jalr    ra
       e:       b2 40   lw      ra, 12(sp)
      10:       41 01   addi    sp, sp, 16
      12:       82 80   ret

$(rustc +nightly --print sysroot)/bin/llvm-nm target/riscv32imc-unknown-none-elf/release/libfoo.rlib

foo-5c3d4a3cd43899d6.foo.axz7xdhy-cgu.0.rcgu.o:
         U __atomic_load_4
00000000 T foo

So the IMC target should have max_atomic_width: None.

P.S. Could you push new commits rather than rewriting the existing ones? New commits are easier to review.

@dvc94ch
Copy link
Contributor Author

dvc94ch commented Aug 30, 2018

Mmh fence is part of the base ISA so I don't know why the above code wouldn't work on imc in this particular case.

@hanna-kruppe
Copy link
Contributor

AFAIK only FENCE.I is in the base ISA, and that one is of no use for implementing atomics.

@dvc94ch
Copy link
Contributor Author

dvc94ch commented Aug 30, 2018

@rkruppe It's in the user spec 2.2 section 2.7 memory model as part of the base ISA.

@dvc94ch
Copy link
Contributor Author

dvc94ch commented Aug 30, 2018

It is my non-expert opinion that llvm is wrong in this case, so we should leave it as is. Since this target is intended for running on fpga's, they are usually single core anyway...

@hanna-kruppe
Copy link
Contributor

Oh, right, this is due to the problem described in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005 -- tl;dr can't emit fence-based inline sequences for some operations and libcalls for other operations on the same memory location because those two might not synchronize correctly with each other.

@japaric
Copy link
Member

japaric commented Aug 30, 2018

@dvc94ch could you file a bug report in LLVM's bugzilla?

Rust targets must not produce binaries with undefined references (i.e. that fail to link) so the IMC target must have max_atomic_width: None until the bug is fixed then the workaround can be removed.

@hanna-kruppe
Copy link
Contributor

If depending on __atomic* functions is not acceptable, I don't think we can ever set max_atomic_width to anything other than None for non-A targets, because max_atomic_width=N implies the availability of CAS and read-modify-write operations that are infeasible to implement (on a multicore system) without the A extension.

@dvc94ch
Copy link
Contributor Author

dvc94ch commented Aug 30, 2018

Then what is the purpose of 173c679#diff-b74c18bf827643ac908307f62d9c1d60R32?

@japaric
Copy link
Member

japaric commented Aug 30, 2018

@dvc94ch thanks!

@bors r+

@rkruppe max_atomic_width: N and atomic_cas: false make the Atomic*.{load,store} API available and leave out the rest of the API.

@bors
Copy link
Contributor

bors commented Aug 30, 2018

📌 Commit 173c679 has been approved by japaric

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 30, 2018
@hanna-kruppe
Copy link
Contributor

Oh, good to know! However, as mentioned above there are very good reasons for LLVM to expand atomic loads and stores to libcalls without the A extension, so I don't expect the bug y'all want to file to be resolved easily if at all.

@bors
Copy link
Contributor

bors commented Sep 1, 2018

⌛ Testing commit 173c679 with merge e6381a7...

bors added a commit that referenced this pull request Sep 1, 2018
[RISCV] Use lld as the default linker; Enable C extension; Add riscv32imc-unknown-none-elf target

The riscv32imc-unknown-none-elf target is intended for soft cores.

The riscv32imc target is supported by the following popular soft cores:

picorv32: https://github.com/cliffordwolf/picorv32
vexriscv: https://github.com/SpinalHDL/VexRiscv
pulp riscy: https://github.com/pulp-platform/riscv
pulp zero-riscy: https://github.com/pulp-platform/zero-riscy
@bors
Copy link
Contributor

bors commented Sep 1, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: japaric
Pushing e6381a7 to master...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants