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

Add riscv64imc-unknown-none-elf target #58012

Closed
wants to merge 3 commits into from

Conversation

fintelia
Copy link
Contributor

These changes are based on 8dfd5c3 which added the riscv32imc target.

CC: rust-embedded/wg/issues/218

@rust-highfive
Copy link
Collaborator

r? @cramertj

(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 Jan 30, 2019

pub fn target() -> TargetResult {
Ok(Target {
data_layout: "e-m:e-i64:64-n64-S128".to_string(),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is this the correct data layout to pass to LLVM? I read https://llvm.org/docs/LangRef.html#data-layout but I'm not 100% sure I got everything correct

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok. That version seems to be equivalent, since p:64:64:64 and f128:128:128 are default. Though I don't quite understand why the defaults have an extra section to them... Should I copy over the configuration from lowRISC?

Copy link
Member

Choose a reason for hiding this comment

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

Currently rustc verifies that the data layout passed to LLVM matches the default data-layout for the target. IIRC it is an ICE or an error otherwise, don’t remember which exactly.

So you have to have exactly the same string as the backend you’re hoping to use.

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe it doesn't matter, but I think being consistent with the clang driver isn't a bad policy

@fintelia fintelia changed the title Add riscv64imc target Add riscv64imc-unknown-none-elf target Jan 30, 2019
@dvc94ch
Copy link
Contributor

dvc94ch commented Jan 30, 2019

Can you make the target riscv64-imacfd-unknown-none-elf? I think that is the most common target. When the afd extensions become available we can then simply enable them without having to rename everything.

@Disasm
Copy link
Contributor

Disasm commented Jan 30, 2019

+1 for riscv64-imacfd-unknown-none-elf (however, in riscv-spec-v2.2 it's spelled as imafdc, see table 22.1)

@fintelia
Copy link
Contributor Author

imafd is often shorted to g, which would translate to riscv64gc-unknown-non-elfand is a bit simpler to read

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:0c8a3309:start=1548881063403669922,finish=1548881595050918667,duration=531647248745
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
Setting environment variables from .travis.yml
$ export IMAGE=x86_64-gnu-llvm-6.0
---

[00:04:29] travis_fold:start:tidy
travis_time:start:tidy
tidy check
[00:04:29] tidy error: /checkout/src/librustc_target/spec/riscv64imc_unknown_none_elf.rs:1: copyright notices attributed to the Rust Project Developers are deprecated
[00:04:31] some tidy checks failed
[00:04:31] 
[00:04:31] 
[00:04:31] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0-tools-bin/tidy" "/checkout/src" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "--no-vendor" "--quiet"
[00:04:31] 
[00:04:31] 
[00:04:31] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap test src/tools/tidy
[00:04:31] Build completed unsuccessfully in 0:00:48
[00:04:31] Build completed unsuccessfully in 0:00:48
[00:04:31] make: *** [tidy] Error 1
[00:04:31] Makefile:68: recipe for target 'tidy' failed
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:140903b8
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Wed Jan 30 20:57:57 UTC 2019
---
travis_time:end:10da0a4c:start=1548881878566081040,finish=1548881878571240096,duration=5159056
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:01a0665a
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb --batch -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:18c1875b
travis_time:start:18c1875b
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers: No such file or directory
travis_fold:end:after_failure.5
travis_fold:start:after_failure.6
travis_time:start:051008a0
$ dmesg | grep -i kill

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@Disasm
Copy link
Contributor

Disasm commented Jan 30, 2019

Not sure, but probably features: "+m,+c".to_string(), line needs to be updated.

@Centril
Copy link
Contributor

Centril commented Jan 30, 2019

r? @nagisa

@rust-highfive rust-highfive assigned nagisa and unassigned cramertj Jan 30, 2019
@jethrogb
Copy link
Contributor

Doesn't this need an update of the LLVM submodule as well to work?

Can you make the target riscv64-imacfd-unknown-none-elf?

There is no F & D support in LLVM yet. A G target can be added later, although I think it makes more sense to add OS-specific G targets.

@fintelia
Copy link
Contributor Author

Pure riscv64ic code can run on a riscv64gc processor. Thus, we can claim the target supports F & D even if we never generate code that uses those extensions. When LLVM is suitably updated, anyone using the target will automatically get faster floating point support. I also think that 64bit G + C makes sense as a target because it corresponds to what any laptop, desktop or server will have. The other 64-bit variants are likely to only be useful on very specific embedded platforms that for some reason need to work with lots of memory but can't afford large cores.

@fintelia
Copy link
Contributor Author

Travis CI now passes, but I'm not actually sure how to test these changes. Does Travis do any checking of new targets? Are there any tests outside of continuous integration that I should be running?

@jethrogb
Copy link
Contributor

jethrogb commented Jan 31, 2019

Does Travis do any checking of new targets?

You have added a tier 3 target, so no. Edit: sorry, you've added a tier 2 target, but core only. (I didn't know this was something we supported? How does rustbuild even know not to build std? The forge page probably needs to be updated to reflect this) This means that when the reviewer approves your PR, a full build of core/alloc will be done for your target.

Are there any tests outside of continuous integration that I should be running?

Yes, you should build a compiler with your changes and core for your target, and then you should try to compile something. Probably something like this:

./x.py build -i --stage 1 src/libcore --target riscv64gc-unknown-none-elf

See https://rust-lang.github.io/rustc-guide/how-to-build-and-run.html

@fintelia
Copy link
Contributor Author

You have added a tier 3 target

That page indicates that tier 3 targets don't have official builds, but the other riscv targets do have toolchains distributed via rustup. Am I misunderstanding, or is there something else required to get included in rustup?

@jethrogb
Copy link
Contributor

That page indicates that tier 3 targets don't have official builds, but the other riscv targets do have toolchains distributed via rustup. Am I misunderstanding, or is there something else required to get included in rustup?

Sorry, this was my mistake, see my updated comment.

@Disasm
Copy link
Contributor

Disasm commented Jan 31, 2019

@fintelia, @jethrogb

The other 64-bit variants are likely to only be useful on very specific embedded platforms that for some reason need to work with lots of memory but can't afford large cores.

FU540-C000 uses RV64IMAC for their Monitor Core, so target riscv64imac-unknown-none-elf makes sense. If we have no F & D support, maybe we can implement support for IMAC target, and add support for GC target later. If it's ok to have GC target now, I can add IMAC target in a separate PR.

@jethrogb
Copy link
Contributor

jethrogb commented Jan 31, 2019

When LLVM is suitably updated, anyone using the target will automatically get faster floating point support.

I don't think we should have a target where using floating point types doesn't work only when the compiler gets to codegen.

linker: Some("rust-lld".to_string()),
cpu: "generic-rv64".to_string(),
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005
max_atomic_width: None, //Some(32),
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

For rv32 yes, the rv64 target still is missing it I think. You can test it by trying to build this:

#![allow(warnings)]
#![crate_type = "lib"]
#![no_std]

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

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

@dvc94ch
Copy link
Contributor

dvc94ch commented Jan 31, 2019

I don't think we should have a target where using floating point types doesn't work only when the compiler gets to codegen.

Can someone write a small floating point example and make sure it generates appropriate code? I'm not sure if enabling the +f and +d extensions will prevent rust/llvm from using compiler-rt or not.

@dvc94ch
Copy link
Contributor

dvc94ch commented Jan 31, 2019

Also since I haven't really looked into how floating point support works there might be some compiler-builtins missing.

@fintelia
Copy link
Contributor Author

fintelia commented Jan 31, 2019

@jethrogb I've tried the build command you suggested but keep getting back an error about being unable to create an LLVM TargetMachine. The same thing happens even if I target the riscv32imac-unknown-none-elf target which is known to work.

Assembling stage1 compiler (x86_64-unknown-linux-gnu)
Building stage1 std artifacts (x86_64-unknown-linux-gnu -> riscv32imac-unknown-none-elf)
error: failed to run `rustc` to learn about target-specific information

Caused by:
  process didn't exit successfully: `/home/jonathan/git/rust/build/bootstrap/debug/rustc - --crate-name ___ --print=file-names --target riscv32imac-unknown-none-elf --crate-type bin --crate-type rlib --crate-type dylib --crate-type cdylib --crate-type staticlib --crate-type proc-macro` (exit code: 1)
--- stderr
error: Could not create LLVM TargetMachine for triple: riscv32: No available targets are compatible with triple "riscv32"

command did not execute successfully: "/home/jonathan/git/rust/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "--target" "riscv32imac-unknown-none-elf" "-j" "4" "--release" "-p" "alloc" "--manifest-path" "/home/jonathan/git/rust/src/liballoc/Cargo.toml" "--features" "compiler-builtins-mem" "--message-format" "json"
expected success, got: exit code: 101
failed to run: /home/jonathan/git/rust/build/bootstrap/debug/bootstrap build -i --stage 1 src/libcore --target riscv32imac-unknown-none-elf
Build completed unsuccessfully in 0:03:29

@dvc94ch Floating point math does seem to work on the existing riscv32imac target. For instance, this code (with a custom println macro) produces correct output, although takes a few seconds to run:

let mut i = 1.0;
let mut sum = 0.0f32;
while i < 40_000_000.0 {
    sum += 1.0 / i - 1.0 / (i + 2.0);
    i += 4.0;
}
println!("pi = {}", 4.0 * sum);

@Disasm
Copy link
Contributor

Disasm commented Jan 31, 2019

@fintelia Same here. Building Rust with make doesn't help either.

@Disasm
Copy link
Contributor

Disasm commented Jan 31, 2019

@fintelia probably, we need to uncomment this line in config.toml...
experimental-targets = "WebAssembly;RISCV"

@fintelia
Copy link
Contributor Author

Were you able to get it to compile with that change? It doesn't seem to have any effect for me

@Disasm
Copy link
Contributor

Disasm commented Feb 1, 2019

@fintelia Now I can build riscv32* targets, but builds for riscv64* targets are failed for different reasons:
riscv64imc-unknown-none-elf: build hangs forever.
riscv64imac-unknown-none-elf (with +a, but atomic_cas=false): libcore build failed with LLVM ERROR
riscv64imfdc-unknown-none-elf: bootstrap rustc crashes with SIGSEGV/SIGBUS

@fintelia
Copy link
Contributor Author

fintelia commented Feb 4, 2019

@fintelia Now I can build riscv32* targets, but builds for riscv64* targets are failed for different reasons:
riscv64imc-unknown-none-elf: build hangs forever.
riscv64imac-unknown-none-elf (with +a, but atomic_cas=false): libcore build failed with LLVM ERROR
riscv64imfdc-unknown-none-elf: bootstrap rustc crashes with SIGSEGV/SIGBUS

@nagisa or @jethrogb do either of you have any suggestions on how to debug this?

@nagisa
Copy link
Member

nagisa commented Feb 4, 2019

Debugging a hang is probably best by getting a coredump and loading it up in the debugger (or just attaching the debugger directly).

LLVM ERROR: attach a debugger and get a callstack at the time this assertion is triggered;

SIGSEGV/SIGBUS... coredump or debugger and look at the callstack/instructions around the area.

@fintelia
Copy link
Contributor Author

fintelia commented Feb 5, 2019

I attached GDB and was able to establish that the hang seems to be happening within the codegen code while compiling libcore. Specifically, the function llvm::SelectionDAG::Combine from /r/r/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so never returns.

Is there anyone with experience with this part of the code that might be able to dig further?

Build output:

jonathan@Jonathan-Ubuntu:/r/r$ ./x.py build -i --stage 1 src/libcore --target riscv64gc-unknown-none-elf
Updating only changed submodules
Submodules updated in 0.02 seconds
    Finished dev [unoptimized] target(s) in 0.20s
Building stage0 std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
    Finished release [optimized] target(s) in 0.20s
Copying stage0 std from stage0 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Building stage0 test artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
    Finished release [optimized] target(s) in 0.18s
Copying stage0 test from stage0 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Building stage0 compiler artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
    Finished release [optimized] target(s) in 0.21s
Copying stage0 rustc from stage0 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu / x86_64-unknown-linux-gnu)
Building stage0 codegen artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu, llvm)
    Finished release [optimized] target(s) in 0.18s
Assembling stage1 compiler (x86_64-unknown-linux-gnu)
Building stage1 std artifacts (x86_64-unknown-linux-gnu -> riscv64gc-unknown-none-elf)
   Compiling core v0.0.0 (/r/r/src/libcore)
    Building [========================>                                  ] 3/7: core                   

Backtrace:

#9  0x00007f4aaca9de3a in llvm::SelectionDAG::Combine(llvm::CombineLevel, llvm::AAResults*, llvm::CodeGenOpt::Level) ()
   from /r/r/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so
#10 0x00007f4aacc13c00 in llvm::SelectionDAGISel::CodeGenAndEmitDAG() ()
   from /r/r/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so
#11 0x00007f4aacc195b5 in llvm::SelectionDAGISel::SelectAllBasicBlocks(llvm::Function const&) ()
   from /r/r/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so
#12 0x00007f4aacc1b2c2 in llvm::SelectionDAGISel::runOnMachineFunction(llvm::MachineFunction&) [clone .part.987] ()
   from /r/r/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so
#13 0x00007f4aace64d2e in llvm::MachineFunctionPass::runOnFunction(llvm::Function&) [clone .part.41] ()
   from /r/r/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so
#14 0x00007f4aad96af09 in llvm::FPPassManager::runOnFunction(llvm::Function&) ()
   from /r/r/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so
#15 0x00007f4aad96afb9 in llvm::FPPassManager::runOnModule(llvm::Module&) ()
   from /r/r/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so
#16 0x00007f4aad96a338 in llvm::legacy::PassManagerImpl::run(llvm::Module&) ()
   from /r/r/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so
#17 0x00007f4aab9f5b04 in LLVMRustWriteOutputFile () from /r/r/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so
#18 0x00007f4aab90fa8c in rustc_codegen_llvm::back::write::write_output_file (handler=0x7f4aa83a7e20, target=0x7f4a580a4030, pm=0x7f4a5816dc40, m=0x0, 
    output=<error reading variable: access outside bounds of object referenced via synthetic pointer>, file_type=rustc_codegen_llvm::llvm_::ffi::FileType::ObjectFile)
    at src/librustc_codegen_llvm/back/write.rs:76
#19 0x00007f4aab9435cc in rustc_codegen_llvm::back::write::codegen::{{closure}}::{{closure}} (cpm=0x7f4a5803c580) at src/librustc_codegen_llvm/back/write.rs:592
#20 rustc_codegen_llvm::back::write::codegen::with_codegen (tm=<optimized out>, llmod=<optimized out>, f=..., no_builtins=<optimized out>)
    at src/librustc_codegen_llvm/back/write.rs:479
#21 rustc_codegen_llvm::back::write::codegen::{{closure}} () at src/librustc_codegen_llvm/back/write.rs:591
#22 0x00007f4aab941d0c in rustc::util::common::time_ext (do_it=<optimized out>, 
    sess=<unknown type in /r/r/build/x86_64-unknown-linux-gnu/stage1/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends/librustc_codegen_llvm-llvm.so, CU 0x1bc4150, DIE 0x1bd9e25>, 
    what=..., f=...) at /r/r/src/librustc/util/common.rs:150
#23 0x00007f4aab912c09 in rustc_codegen_llvm::back::write::codegen (cgcx=<optimized out>, diag_handler=<optimized out>, module=..., config=<optimized out>, timeline=<optimized out>)
    at src/librustc_codegen_llvm/back/write.rs:528
#24 0x00007f4aab87c15b in <rustc_codegen_llvm::LlvmCodegenBackend as rustc_codegen_ssa::traits::write::WriteBackendMethods>::codegen (cgcx=<optimized out>, diag_handler=0x0, 
    config=<optimized out>, timeline=<optimized out>, module=...) at src/librustc_codegen_llvm/lib.rs:206
#25 rustc_codegen_ssa::back::write::execute_optimize_work_item (cgcx=<optimized out>, module_config=0x7f4a714db260, timeline=<optimized out>, module=...)
    at /r/r/src/librustc_codegen_ssa/back/write.rs:778
#26 rustc_codegen_ssa::back::write::execute_work_item (cgcx=<optimized out>, work_item=<optimized out>, timeline=0x7f4aa83a8080) at /r/r/src/librustc_codegen_ssa/back/write.rs:703
#27 0x00007f4aab86bb78 in rustc_codegen_ssa::back::write::spawn_work::{{closure}} () at /r/r/src/librustc_codegen_ssa/back/write.rs:1570

@nagisa
Copy link
Member

nagisa commented Feb 5, 2019

That is a bug in the backend. You may have some success by looking at what LLVM is doing by looking at the output of -Cllvm-args=-print-before-all or -Cllvm-args=-print-after-all. Make sure you have a minimal test case before doing that, otherwise the output will 100% overwhelm you.

@fintelia
Copy link
Contributor Author

fintelia commented Feb 9, 2019

I was able to get some output from --Cllvm-args=print-before="simplifycfg"but llc rejected processing it (something about an argument mismatch a couple hundred lines in). I tried a couple different ways of getting normal bytecode/IR output from LLVM but was unable to anything working. I also wasn't able to run any builds without relying on the bootstrap.py wrapper, blocking any chance at producing a more minimal example.

Unfortunately I don't have more time to commit to this issue right now so if @Disasm, @dvc94ch or anyone else wants to take over, please do

@dvc94ch
Copy link
Contributor

dvc94ch commented Feb 9, 2019 via email

@Disasm
Copy link
Contributor

Disasm commented Feb 9, 2019

@fintelia Thanks for the effort! I will try to experiment with updated LLVM soon.

@Disasm Disasm mentioned this pull request Feb 9, 2019
@davidlt
Copy link

davidlt commented Feb 10, 2019

"RISC-V Unix-class systems implement the RV64GC ISA with supervisor mode and the Sv39 page-based virtual-memory scheme."
From: https://github.com/riscv/riscv-platform-specs/blob/master/riscv-unix.md

All Linux distributions are targeting RV64GC (Fedora, Debian, openSUSE, etc.)

There are still missing some pieces. TLS is under review. PIC is missing implementation. Linux hard float ABIs are also not implemented. Not sure how all that affects Rust directly.

Alex Bradbury presented the current status at FODEM 2019: https://fosdem.org/2019/schedule/event/riscvllvmclang/

@Disasm
Copy link
Contributor

Disasm commented Feb 10, 2019

I managed to compile Rust for RV64IMAC target with some LLVM patches, however rust-lld was not able to link a test application due to incompatible relocations. The problem is triggered by this code:

rust-lld: error: riscv-rt/src/lib.rs:224: relocation R_RISCV_HI20 out of range: 2147483648 is not in [-2147483648, 2147483647]
rust-lld: error: riscv-rt/src/lib.rs:224: relocation R_RISCV_LO12_I out of range: 2147483648 is not in [-2147483648, 2147483647]

Assembly code:

   4:	00000537          	lui	a0,0x0
			4: R_RISCV_HI20	_sbss
   8:	00050513          	mv	a0,a0
			8: R_RISCV_LO12_I	_sbss

Another assembly code (for la gp, __global_pointer$ instruction) looks like this:

   0:	00000197          	auipc	gp,0x0
			0: R_RISCV_PCREL_HI20	__global_pointer$
			0: R_RISCV_RELAX	*ABS*
   4:	00018193          	mv	gp,gp
			4: R_RISCV_PCREL_LO12_I	.L0 
			4: R_RISCV_RELAX	*ABS*

and linker doesn't complain about it.

A linker script that is used to build the test application maps RAM region into 0x80000000 address, which is invalid for R_RISCV_HI20+R_RISCV_LO12_I.

Changing relocation_model from static to pic leads to an error during the Rust toolchain build. Setting code_model to large does not help either.

Any ideas?

@davidlt
Copy link

davidlt commented Feb 10, 2019

CC @asb

@dvc94ch
Copy link
Contributor

dvc94ch commented Feb 10, 2019

@Disasm Awesome progress! I'll mention some stuff you can try for completeness, even though I'm sure you thought of it yourself:

@Disasm
Copy link
Contributor

Disasm commented Feb 10, 2019

@dvc94ch I'm able to link with different RAM base addresses (0x40000000 for example), even float instructions are generated for RV64GC target. The main problem is that Rust or LLVM generates wrong instructions (static loads instead of pc-relative) which renders Rust toolchain useless for any addresses >=0x80000000. Trying to figure out the cause of this problem...
BTW it's a great coincidence that I have 0x80000000 in my memory.x file, now we at least know about the problem with relocs :) And yes, RAM on HiFive Unleased also starts from 0x80000000.

@Disasm
Copy link
Contributor

Disasm commented Feb 10, 2019

Looks like the answer is "not supported yet".

  1. MO_PCREL_HI is never used.
  2. It should be used here, but for position-independent case, which is not supported.
  3. This is the same problem that I faced with relocation_model==pic.

So... I suggest adding support for both riscv64imac and riscv64gc targets, but without position-independent addressing. If the corresponding patches arrive to LLVM, we will fix RV64 targets. If you think that riscv64imc should be added too, let me know. I am not aware of any hardware that can use it.

@davidlt
Copy link

davidlt commented Feb 11, 2019

True, the PIC is not yet supported in LLVM for RISC-V. Regarding riscv64imc do you really need it? The kernel requires A extension to be present to boot Linux. Otherwise riscv64gc and riscv64imac (riscv64gc without single and double precision floating point) makes sense. E.g. for grub2 the target is rv64imac for GCC.

@Disasm
Copy link
Contributor

Disasm commented Feb 11, 2019

@davidlt I personally do not need riscv64imc, so I asking if someone needs it. For example, PULPino 32-bit core does not have A extension.

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-6.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
travis_time:end:057a6a87:start=1549992244352318512,finish=1549992247705472594,duration=3353154082
$ git checkout -qf FETCH_HEAD
travis_fold:end:git.checkout

Encrypted environment variables have been removed for security reasons.
See https://docs.travis-ci.com/user/pull-requests/#pull-requests-and-security-restrictions
$ export SCCACHE_BUCKET=rust-lang-ci-sccache2
$ export SCCACHE_REGION=us-west-1
Setting environment variables from .travis.yml
$ export IMAGE=x86_64-gnu-llvm-6.0
---
[00:06:55]    Compiling rustc-rayon v0.1.1
[00:06:58]    Compiling tempfile v3.0.5
[00:06:58]    Compiling rustc_data_structures v0.0.0 (/checkout/src/librustc_data_structures)
[00:07:01]    Compiling arena v0.0.0 (/checkout/src/libarena)
[00:07:01] error[E0432]: unresolved import `spec`
[00:07:01]  --> src/librustc_target/spec/riscv64gc_unknown_none_elf.rs:1:5
[00:07:01]   |
[00:07:01] 1 | use spec::{LinkerFlavor, LldFlavor, PanicStrategy,
[00:07:01]   |     ^^^^ did you mean `crate::spec`?
[00:07:01]   |
[00:07:01]   = note: `use` statements changed in Rust 2018; read more at <https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-clarity.html>
[00:07:01]    Compiling syntax_pos v0.0.0 (/checkout/src/libsyntax_pos)
[00:07:02] error: aborting due to previous error
[00:07:02] 
[00:07:02] For more information about this error, try `rustc --explain E0432`.
[00:07:02] For more information about this error, try `rustc --explain E0432`.
[00:07:02] error: Could not compile `rustc_target`.
[00:07:02] warning: build failed, waiting for other jobs to finish...
[00:07:05] error: build failed
[00:07:05] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "--target" "x86_64-unknown-linux-gnu" "-j" "4" "--release" "--locked" "--color" "always" "--features" "" "--manifest-path" "/checkout/src/rustc/Cargo.toml" "--message-format" "json"
[00:07:05] expected success, got: exit code: 101
[00:07:05] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap build
[00:07:05] Build completed unsuccessfully in 0:02:05
[00:07:05] Makefile:18: recipe for target 'all' failed
[00:07:05] make: *** [all] Error 1
The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:0cfdb5a0
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)
Tue Feb 12 17:31:32 UTC 2019

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@Disasm
Copy link
Contributor

Disasm commented Feb 12, 2019

Superseded by #58406

@fintelia fintelia closed this Feb 12, 2019
bors added a commit that referenced this pull request Feb 14, 2019
Add riscv64{imac,gc}-unknown-none-elf targets

Previous attempt by @fintelia: #58012

Related: rust-embedded/wg#218
bors added a commit that referenced this pull request Feb 15, 2019
Add riscv64{imac,gc}-unknown-none-elf targets

Previous attempt by @fintelia: #58012

Related: rust-embedded/wg#218
bors added a commit that referenced this pull request Feb 15, 2019
Add riscv64{imac,gc}-unknown-none-elf targets

Previous attempt by @fintelia: #58012

Related: rust-embedded/wg#218
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-review Status: Awaiting review from the assignee but also interested parties.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants