Skip to content

Commit 62f6e84

Browse files
authored
Merge pull request #1398 from bjorn3/riscv_support
Add riscv64 linux support
2 parents 2f74b68 + 1848d25 commit 62f6e84

File tree

5 files changed

+79
-28
lines changed

5 files changed

+79
-28
lines changed

.github/workflows/main.yml

+9-1
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ jobs:
5050
- os: ubuntu-latest
5151
env:
5252
TARGET_TRIPLE: aarch64-unknown-linux-gnu
53-
# s390x requires QEMU 6.1 or greater, we could build it from source, but ubuntu 22.04 comes with 6.2 by default
5453
- os: ubuntu-latest
5554
env:
5655
TARGET_TRIPLE: s390x-unknown-linux-gnu
56+
- os: ubuntu-latest
57+
env:
58+
TARGET_TRIPLE: riscv64gc-unknown-linux-gnu
5759
- os: windows-latest
5860
env:
5961
TARGET_TRIPLE: x86_64-pc-windows-msvc
@@ -92,6 +94,12 @@ jobs:
9294
sudo apt-get update
9395
sudo apt-get install -y gcc-s390x-linux-gnu qemu-user
9496
97+
- name: Install riscv64gc toolchain and qemu
98+
if: matrix.env.TARGET_TRIPLE == 'riscv64gc-unknown-linux-gnu'
99+
run: |
100+
sudo apt-get update
101+
sudo apt-get install -y gcc-riscv64-linux-gnu qemu-user
102+
95103
- name: Prepare dependencies
96104
run: ./y.sh prepare
97105

build_system/utils.rs

+10
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ impl Compiler {
4242
"/usr/s390x-linux-gnu".to_owned(),
4343
];
4444
}
45+
"riscv64gc-unknown-linux-gnu" => {
46+
// We are cross-compiling for riscv64. Use the correct linker and run tests in qemu.
47+
self.rustflags.push("-Clinker=riscv64-linux-gnu-gcc".to_owned());
48+
self.rustdocflags.push("-Clinker=riscv64-linux-gnu-gcc".to_owned());
49+
self.runner = vec![
50+
"qemu-riscv64".to_owned(),
51+
"-L".to_owned(),
52+
"/usr/riscv64-linux-gnu".to_owned(),
53+
];
54+
}
4555
"x86_64-pc-windows-gnu" => {
4656
// We are cross-compiling for Windows. Run tests in wine.
4757
self.runner = vec!["wine".to_owned()];

scripts/setup_rust_fork.sh

-20
Original file line numberDiff line numberDiff line change
@@ -13,23 +13,6 @@ git checkout "$(rustc -V | cut -d' ' -f3 | tr -d '(')"
1313
git -c user.name=Dummy -c [email protected] -c commit.gpgSign=false \
1414
am ../patches/*-stdlib-*.patch
1515

16-
git apply - <<EOF
17-
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
18-
index d95b5b7f17f..00b6f0e3635 100644
19-
--- a/library/alloc/Cargo.toml
20-
+++ b/library/alloc/Cargo.toml
21-
@@ -8,7 +8,7 @@ edition = "2018"
22-
23-
[dependencies]
24-
core = { path = "../core" }
25-
-compiler_builtins = { version = "0.1.40", features = ['rustc-dep-of-std'] }
26-
+compiler_builtins = { version = "0.1.66", features = ['rustc-dep-of-std', 'no-asm'] }
27-
28-
[dev-dependencies]
29-
rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
30-
rand_xorshift = "0.3.0"
31-
EOF
32-
3316
cat > config.toml <<EOF
3417
change-id = 115898
3518
@@ -49,9 +32,6 @@ verbose-tests = false
4932
EOF
5033
popd
5134

52-
# FIXME remove once inline asm is fully supported
53-
export RUSTFLAGS="$RUSTFLAGS --cfg=rustix_use_libc"
54-
5535
export CFG_VIRTUAL_RUST_SOURCE_BASE_DIR="$(cd build/stdlib; pwd)"
5636

5737
# Allow the testsuite to use llvm tools

src/global_asm.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
8181
}
8282
}
8383

84+
pub(crate) fn asm_supported(tcx: TyCtxt<'_>) -> bool {
85+
cfg!(feature = "inline_asm") && !tcx.sess.target.is_like_windows
86+
}
87+
8488
#[derive(Debug)]
8589
pub(crate) struct GlobalAsmConfig {
8690
asm_enabled: bool,
@@ -90,10 +94,8 @@ pub(crate) struct GlobalAsmConfig {
9094

9195
impl GlobalAsmConfig {
9296
pub(crate) fn new(tcx: TyCtxt<'_>) -> Self {
93-
let asm_enabled = cfg!(feature = "inline_asm") && !tcx.sess.target.is_like_windows;
94-
9597
GlobalAsmConfig {
96-
asm_enabled,
98+
asm_enabled: asm_supported(tcx),
9799
assembler: crate::toolchain::get_toolchain_binary(tcx.sess, "as"),
98100
output_filenames: tcx.output_filenames(()).clone(),
99101
}

src/inline_asm.rs

+55-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_span::sym;
88
use rustc_target::asm::*;
99
use target_lexicon::BinaryFormat;
1010

11+
use crate::global_asm::asm_supported;
1112
use crate::prelude::*;
1213

1314
enum CInlineAsmOperand<'tcx> {
@@ -44,9 +45,13 @@ pub(crate) fn codegen_inline_asm<'tcx>(
4445
) {
4546
// FIXME add .eh_frame unwind info directives
4647

47-
if !template.is_empty()
48-
&& (cfg!(not(feature = "inline_asm")) || fx.tcx.sess.target.is_like_windows)
49-
{
48+
if !asm_supported(fx.tcx) {
49+
if template.is_empty() {
50+
let destination_block = fx.get_block(destination.unwrap());
51+
fx.bcx.ins().jump(destination_block, &[]);
52+
return;
53+
}
54+
5055
// Used by panic_abort
5156
if template[0] == InlineAsmTemplatePiece::String("int $$0x29".to_string()) {
5257
fx.bcx.ins().trap(TrapCode::User(1));
@@ -144,6 +149,16 @@ pub(crate) fn codegen_inline_asm<'tcx>(
144149
return;
145150
}
146151

152+
// Used by core::hint::spin_loop()
153+
if template[0]
154+
== InlineAsmTemplatePiece::String(".insn i 0x0F, 0, x0, x0, 0x010".to_string())
155+
&& template.len() == 1
156+
{
157+
let destination_block = fx.get_block(destination.unwrap());
158+
fx.bcx.ins().jump(destination_block, &[]);
159+
return;
160+
}
161+
147162
// Used by measureme
148163
if template[0] == InlineAsmTemplatePiece::String("xor %eax, %eax".to_string())
149164
&& template[1] == InlineAsmTemplatePiece::String("\n".to_string())
@@ -223,6 +238,16 @@ pub(crate) fn codegen_inline_asm<'tcx>(
223238
fx.bcx.ins().jump(destination_block, &[]);
224239
return;
225240
}
241+
242+
if cfg!(not(feature = "inline_asm")) {
243+
fx.tcx.sess.span_err(
244+
span,
245+
"asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift",
246+
);
247+
} else {
248+
fx.tcx.sess.span_err(span, "asm! and global_asm! are not yet supported on Windows");
249+
}
250+
return;
226251
}
227252

228253
let operands = operands
@@ -745,6 +770,13 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
745770
// x19 is reserved by LLVM for the "base pointer", so rustc doesn't allow using it
746771
generated_asm.push_str(" mov x19, x0\n");
747772
}
773+
InlineAsmArch::RiscV64 => {
774+
generated_asm.push_str(" addi sp, sp, -16\n");
775+
generated_asm.push_str(" sd ra, 8(sp)\n");
776+
generated_asm.push_str(" sd s1, 0(sp)\n"); // s1 is callee saved
777+
// s1/x9 is reserved by LLVM for the "base pointer", so rustc doesn't allow using it
778+
generated_asm.push_str(" mv s1, a0\n");
779+
}
748780
_ => unimplemented!("prologue for {:?}", arch),
749781
}
750782
}
@@ -761,6 +793,12 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
761793
generated_asm.push_str(" ldp fp, lr, [sp], #32\n");
762794
generated_asm.push_str(" ret\n");
763795
}
796+
InlineAsmArch::RiscV64 => {
797+
generated_asm.push_str(" ld s1, 0(sp)\n");
798+
generated_asm.push_str(" ld ra, 8(sp)\n");
799+
generated_asm.push_str(" addi sp, sp, 16\n");
800+
generated_asm.push_str(" ret\n");
801+
}
764802
_ => unimplemented!("epilogue for {:?}", arch),
765803
}
766804
}
@@ -771,7 +809,10 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
771809
generated_asm.push_str(" ud2\n");
772810
}
773811
InlineAsmArch::AArch64 => {
774-
generated_asm.push_str(" brk #0x1");
812+
generated_asm.push_str(" brk #0x1\n");
813+
}
814+
InlineAsmArch::RiscV64 => {
815+
generated_asm.push_str(" ebreak\n");
775816
}
776817
_ => unimplemented!("epilogue_noreturn for {:?}", arch),
777818
}
@@ -794,6 +835,11 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
794835
reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap();
795836
writeln!(generated_asm, ", [x19, 0x{:x}]", offset.bytes()).unwrap();
796837
}
838+
InlineAsmArch::RiscV64 => {
839+
generated_asm.push_str(" sd ");
840+
reg.emit(generated_asm, InlineAsmArch::RiscV64, None).unwrap();
841+
writeln!(generated_asm, ", 0x{:x}(s1)", offset.bytes()).unwrap();
842+
}
797843
_ => unimplemented!("save_register for {:?}", arch),
798844
}
799845
}
@@ -815,6 +861,11 @@ impl<'tcx> InlineAssemblyGenerator<'_, 'tcx> {
815861
reg.emit(generated_asm, InlineAsmArch::AArch64, None).unwrap();
816862
writeln!(generated_asm, ", [x19, 0x{:x}]", offset.bytes()).unwrap();
817863
}
864+
InlineAsmArch::RiscV64 => {
865+
generated_asm.push_str(" ld ");
866+
reg.emit(generated_asm, InlineAsmArch::RiscV64, None).unwrap();
867+
writeln!(generated_asm, ", 0x{:x}(s1)", offset.bytes()).unwrap();
868+
}
818869
_ => unimplemented!("restore_register for {:?}", arch),
819870
}
820871
}

0 commit comments

Comments
 (0)