Skip to content

Commit e702b5c

Browse files
authored
Unrolled build for rust-lang#130555
Rollup merge of rust-lang#130555 - hegza:rv32e, r=workingjubilee Initial support for riscv32{e|em|emc}_unknown_none_elf We have a research prototype of an RV32EMC target and have been successfully running the e, em, emc programs on it. I'm hoping upstreaming this configuration would make the target maintenance slightly easier. Configuration is based on the respective {i, im, imc} variants. As defined in RISC-V Unprivileged Spec. 20191213, the only change in RVE wrt. RVI is to reduce the number of integer registers to 16 (x0-x15), which also implies - 2 callee saved registers instead of 12 - 32-bit / 4-byte stack alignment instead of 128 bits / 16 bytes My initial presumption is that this will not impact how the target is defined for the compiler but only becomes relevant at the runtime level. I am willing to investigate, though. EDIT: LLVM is now told about the presumed 32-bit stack alignment. `@Disasm` `@romancardenas`
2 parents 2b21f90 + 6edd0b3 commit e702b5c

13 files changed

+825
-1
lines changed

Diff for: compiler/rustc_target/src/spec/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1841,6 +1841,10 @@ supported_targets! {
18411841
("riscv32imac-esp-espidf", riscv32imac_esp_espidf),
18421842
("riscv32imafc-esp-espidf", riscv32imafc_esp_espidf),
18431843

1844+
("riscv32e-unknown-none-elf", riscv32e_unknown_none_elf),
1845+
("riscv32em-unknown-none-elf", riscv32em_unknown_none_elf),
1846+
("riscv32emc-unknown-none-elf", riscv32emc_unknown_none_elf),
1847+
18441848
("riscv32imac-unknown-none-elf", riscv32imac_unknown_none_elf),
18451849
("riscv32imafc-unknown-none-elf", riscv32imafc_unknown_none_elf),
18461850
("riscv32imac-unknown-xous-elf", riscv32imac_unknown_xous_elf),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
2+
3+
pub(crate) fn target() -> Target {
4+
Target {
5+
// The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also
6+
// `options.llvm_abiname`.
7+
data_layout: "e-m:e-p:32:32-i64:64-n32-S32".into(),
8+
llvm_target: "riscv32".into(),
9+
metadata: crate::spec::TargetMetadata {
10+
description: Some("Bare RISC-V (RV32E ISA)".into()),
11+
tier: Some(3),
12+
host_tools: Some(false),
13+
std: Some(false),
14+
},
15+
pointer_width: 32,
16+
arch: "riscv32".into(),
17+
18+
options: TargetOptions {
19+
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
20+
linker: Some("rust-lld".into()),
21+
cpu: "generic-rv32".into(),
22+
// The ilp32e ABI specifies the `data_layout`
23+
llvm_abiname: "ilp32e".into(),
24+
max_atomic_width: Some(32),
25+
atomic_cas: false,
26+
features: "+e,+forced-atomics".into(),
27+
panic_strategy: PanicStrategy::Abort,
28+
relocation_model: RelocModel::Static,
29+
emit_debug_gdb_scripts: false,
30+
eh_frame_header: false,
31+
..Default::default()
32+
},
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
2+
3+
pub(crate) fn target() -> Target {
4+
Target {
5+
// The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also
6+
// `options.llvm_abiname`.
7+
data_layout: "e-m:e-p:32:32-i64:64-n32-S32".into(),
8+
llvm_target: "riscv32".into(),
9+
metadata: crate::spec::TargetMetadata {
10+
description: Some("Bare RISC-V (RV32EM ISA)".into()),
11+
tier: Some(3),
12+
host_tools: Some(false),
13+
std: Some(false),
14+
},
15+
pointer_width: 32,
16+
arch: "riscv32".into(),
17+
18+
options: TargetOptions {
19+
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
20+
linker: Some("rust-lld".into()),
21+
cpu: "generic-rv32".into(),
22+
// The ilp32e ABI specifies the `data_layout`
23+
llvm_abiname: "ilp32e".into(),
24+
max_atomic_width: Some(32),
25+
atomic_cas: false,
26+
features: "+e,+m,+forced-atomics".into(),
27+
panic_strategy: PanicStrategy::Abort,
28+
relocation_model: RelocModel::Static,
29+
emit_debug_gdb_scripts: false,
30+
eh_frame_header: false,
31+
..Default::default()
32+
},
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use crate::spec::{Cc, LinkerFlavor, Lld, PanicStrategy, RelocModel, Target, TargetOptions};
2+
3+
pub(crate) fn target() -> Target {
4+
Target {
5+
// The below `data_layout` is explicitly specified by the ilp32e ABI in LLVM. See also
6+
// `options.llvm_abiname`.
7+
data_layout: "e-m:e-p:32:32-i64:64-n32-S32".into(),
8+
llvm_target: "riscv32".into(),
9+
metadata: crate::spec::TargetMetadata {
10+
description: Some("Bare RISC-V (RV32EMC ISA)".into()),
11+
tier: Some(3),
12+
host_tools: Some(false),
13+
std: Some(false),
14+
},
15+
pointer_width: 32,
16+
arch: "riscv32".into(),
17+
18+
options: TargetOptions {
19+
linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
20+
linker: Some("rust-lld".into()),
21+
cpu: "generic-rv32".into(),
22+
// The ilp32e ABI specifies the `data_layout`
23+
llvm_abiname: "ilp32e".into(),
24+
max_atomic_width: Some(32),
25+
atomic_cas: false,
26+
features: "+e,+m,+c,+forced-atomics".into(),
27+
panic_strategy: PanicStrategy::Abort,
28+
relocation_model: RelocModel::Static,
29+
emit_debug_gdb_scripts: false,
30+
eh_frame_header: false,
31+
..Default::default()
32+
},
33+
}
34+
}

Diff for: src/bootstrap/src/core/sanity.rs

+3
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ pub struct Finder {
3737
const STAGE0_MISSING_TARGETS: &[&str] = &[
3838
// just a dummy comment so the list doesn't get onelined
3939
"armv7-rtems-eabihf",
40+
"riscv32e-unknown-none-elf",
41+
"riscv32em-unknown-none-elf",
42+
"riscv32emc-unknown-none-elf",
4043
];
4144

4245
/// Minimum version threshold for libstdc++ required when using prebuilt LLVM

Diff for: src/doc/rustc/src/platform-support.md

+3
Original file line numberDiff line numberDiff line change
@@ -413,5 +413,8 @@ target | std | host | notes
413413
[`riscv32imafc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 32bit with NuttX
414414
[`riscv64imac-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX
415415
[`riscv64gc-unknown-nuttx-elf`](platform-support/nuttx.md) | * | | RISC-V 64bit with NuttX
416+
[`riscv32e-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32E ISA)
417+
[`riscv32em-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32EM ISA)
418+
[`riscv32emc-unknown-none-elf`](platform-support/riscv32-unknown-none-elf.md) | * | | Bare RISC-V (RV32EMC ISA)
416419

417420
[runs on NVIDIA GPUs]: https://github.com/japaric-archived/nvptx#targets

Diff for: src/doc/rustc/src/platform-support/riscv32-unknown-none-elf.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,4 @@ Rust test-suite on this target.
3535
## Cross-compilation toolchains and C code
3636

3737
This target supports C code. If interlinking with C or C++, you may need to use
38-
`riscv64-unknown-elf-gcc` as a linker instead of `rust-lld`.
38+
`riscv32-unknown-elf-gcc` as a linker instead of `rust-lld`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# `riscv32{e,em,emc}-unknown-none-elf`
2+
3+
**Tier: 3**
4+
5+
Bare-metal target for RISC-V CPUs with the RV32E, RV32EM and RV32EMC ISAs.
6+
7+
## Target maintainers
8+
9+
* Henri Lunnikivi, <henri.lunnikivi@gmail.com>, [@hegza](https://github.com/hegza)
10+
11+
## Requirements
12+
13+
The target is cross-compiled, and uses static linking. No external toolchain is
14+
required and the default `rust-lld` linker works, but you must specify a linker
15+
script.
16+
17+
## Building the target
18+
19+
This target is included in Rust and can be installed via `rustup`.
20+
21+
## Testing
22+
23+
This is a cross-compiled `no-std` target, which must be run either in a
24+
simulator or by programming them onto suitable hardware. It is not possible to
25+
run the Rust test-suite on this target.
26+
27+
## Cross-compilation toolchains and C code
28+
29+
This target supports C code. If interlinking with C or C++, you may need to use
30+
`riscv32-unknown-elf-gcc` as a linker instead of `rust-lld`.

Diff for: tests/assembly/targets/targets-elf.rs

+9
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,15 @@
375375
//@ revisions: riscv32_wrs_vxworks
376376
//@ [riscv32_wrs_vxworks] compile-flags: --target riscv32-wrs-vxworks
377377
//@ [riscv32_wrs_vxworks] needs-llvm-components: riscv
378+
//@ revisions: riscv32e_unknown_none_elf
379+
//@ [riscv32e_unknown_none_elf] compile-flags: --target riscv32e-unknown-none-elf
380+
//@ [riscv32e_unknown_none_elf] needs-llvm-components: riscv
381+
//@ revisions: riscv32em_unknown_none_elf
382+
//@ [riscv32em_unknown_none_elf] compile-flags: --target riscv32em-unknown-none-elf
383+
//@ [riscv32em_unknown_none_elf] needs-llvm-components: riscv
384+
//@ revisions: riscv32emc_unknown_none_elf
385+
//@ [riscv32emc_unknown_none_elf] compile-flags: --target riscv32emc-unknown-none-elf
386+
//@ [riscv32emc_unknown_none_elf] needs-llvm-components: riscv
378387
//@ revisions: riscv32gc_unknown_linux_gnu
379388
//@ [riscv32gc_unknown_linux_gnu] compile-flags: --target riscv32gc-unknown-linux-gnu
380389
//@ [riscv32gc_unknown_linux_gnu] needs-llvm-components: riscv

Diff for: tests/ui/abi/riscv32e-registers.riscv32e.stderr

+194
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
error: invalid operand for instruction
2+
--> $DIR/riscv32e-registers.rs:43:11
3+
|
4+
LL | asm!("li x16, 0");
5+
| ^
6+
|
7+
note: instantiated into assembly here
8+
--> <inline asm>:1:5
9+
|
10+
LL | li x16, 0
11+
| ^
12+
13+
error: invalid operand for instruction
14+
--> $DIR/riscv32e-registers.rs:46:11
15+
|
16+
LL | asm!("li x17, 0");
17+
| ^
18+
|
19+
note: instantiated into assembly here
20+
--> <inline asm>:1:5
21+
|
22+
LL | li x17, 0
23+
| ^
24+
25+
error: invalid operand for instruction
26+
--> $DIR/riscv32e-registers.rs:49:11
27+
|
28+
LL | asm!("li x18, 0");
29+
| ^
30+
|
31+
note: instantiated into assembly here
32+
--> <inline asm>:1:5
33+
|
34+
LL | li x18, 0
35+
| ^
36+
37+
error: invalid operand for instruction
38+
--> $DIR/riscv32e-registers.rs:52:11
39+
|
40+
LL | asm!("li x19, 0");
41+
| ^
42+
|
43+
note: instantiated into assembly here
44+
--> <inline asm>:1:5
45+
|
46+
LL | li x19, 0
47+
| ^
48+
49+
error: invalid operand for instruction
50+
--> $DIR/riscv32e-registers.rs:55:11
51+
|
52+
LL | asm!("li x20, 0");
53+
| ^
54+
|
55+
note: instantiated into assembly here
56+
--> <inline asm>:1:5
57+
|
58+
LL | li x20, 0
59+
| ^
60+
61+
error: invalid operand for instruction
62+
--> $DIR/riscv32e-registers.rs:58:11
63+
|
64+
LL | asm!("li x21, 0");
65+
| ^
66+
|
67+
note: instantiated into assembly here
68+
--> <inline asm>:1:5
69+
|
70+
LL | li x21, 0
71+
| ^
72+
73+
error: invalid operand for instruction
74+
--> $DIR/riscv32e-registers.rs:61:11
75+
|
76+
LL | asm!("li x22, 0");
77+
| ^
78+
|
79+
note: instantiated into assembly here
80+
--> <inline asm>:1:5
81+
|
82+
LL | li x22, 0
83+
| ^
84+
85+
error: invalid operand for instruction
86+
--> $DIR/riscv32e-registers.rs:64:11
87+
|
88+
LL | asm!("li x23, 0");
89+
| ^
90+
|
91+
note: instantiated into assembly here
92+
--> <inline asm>:1:5
93+
|
94+
LL | li x23, 0
95+
| ^
96+
97+
error: invalid operand for instruction
98+
--> $DIR/riscv32e-registers.rs:67:11
99+
|
100+
LL | asm!("li x24, 0");
101+
| ^
102+
|
103+
note: instantiated into assembly here
104+
--> <inline asm>:1:5
105+
|
106+
LL | li x24, 0
107+
| ^
108+
109+
error: invalid operand for instruction
110+
--> $DIR/riscv32e-registers.rs:70:11
111+
|
112+
LL | asm!("li x25, 0");
113+
| ^
114+
|
115+
note: instantiated into assembly here
116+
--> <inline asm>:1:5
117+
|
118+
LL | li x25, 0
119+
| ^
120+
121+
error: invalid operand for instruction
122+
--> $DIR/riscv32e-registers.rs:73:11
123+
|
124+
LL | asm!("li x26, 0");
125+
| ^
126+
|
127+
note: instantiated into assembly here
128+
--> <inline asm>:1:5
129+
|
130+
LL | li x26, 0
131+
| ^
132+
133+
error: invalid operand for instruction
134+
--> $DIR/riscv32e-registers.rs:76:11
135+
|
136+
LL | asm!("li x27, 0");
137+
| ^
138+
|
139+
note: instantiated into assembly here
140+
--> <inline asm>:1:5
141+
|
142+
LL | li x27, 0
143+
| ^
144+
145+
error: invalid operand for instruction
146+
--> $DIR/riscv32e-registers.rs:79:11
147+
|
148+
LL | asm!("li x28, 0");
149+
| ^
150+
|
151+
note: instantiated into assembly here
152+
--> <inline asm>:1:5
153+
|
154+
LL | li x28, 0
155+
| ^
156+
157+
error: invalid operand for instruction
158+
--> $DIR/riscv32e-registers.rs:82:11
159+
|
160+
LL | asm!("li x29, 0");
161+
| ^
162+
|
163+
note: instantiated into assembly here
164+
--> <inline asm>:1:5
165+
|
166+
LL | li x29, 0
167+
| ^
168+
169+
error: invalid operand for instruction
170+
--> $DIR/riscv32e-registers.rs:85:11
171+
|
172+
LL | asm!("li x30, 0");
173+
| ^
174+
|
175+
note: instantiated into assembly here
176+
--> <inline asm>:1:5
177+
|
178+
LL | li x30, 0
179+
| ^
180+
181+
error: invalid operand for instruction
182+
--> $DIR/riscv32e-registers.rs:88:11
183+
|
184+
LL | asm!("li x31, 0");
185+
| ^
186+
|
187+
note: instantiated into assembly here
188+
--> <inline asm>:1:5
189+
|
190+
LL | li x31, 0
191+
| ^
192+
193+
error: aborting due to 16 previous errors
194+

0 commit comments

Comments
 (0)