Skip to content

Commit 4a24aab

Browse files
Rollup merge of rust-lang#96971 - zhaixiaojuan:master, r=wesleywiser
Initial support for loongarch64-unknown-linux-gnu Hi, We hope to add a new port in rust for LoongArch. LoongArch intro LoongArch is a RISC style ISA which is independently designed by Loongson Technology in China. It is divided into two versions, the 32-bit version (LA32) and the 64-bit version (LA64). LA64 applications have application-level backward binary compatibility with LA32 applications. LoongArch is composed of a basic part (Loongson Base) and an expanded part. The expansion part includes Loongson Binary Translation (LBT), Loongson VirtualiZation (LVZ), Loongson SIMD EXtension (LSX) and Loongson Advanced SIMD EXtension(LASX). Currently the LA464 processor core supports LoongArch ISA and the Loongson 3A5000 processor integrates 4 64-bit LA464 cores. LA464 is a four-issue 64-bit high-performance processor core. It can be used as a single core for high-end embedded and desktop applications, or as a basic processor core to form an on-chip multi-core system for server and high-performance machine applications. Documentations: ISA: https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html ABI: https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html More docs can be found at: https://loongson.github.io/LoongArch-Documentation/README-EN.html Since last year, we have locally adapted two versions of rust, rust1.41 and rust1.57, and completed the test locally. I'm not sure if I'm submitting all the patches at once, so I split up the patches and here's one of the commits
2 parents e7271f4 + a3f0046 commit 4a24aab

File tree

21 files changed

+150
-4
lines changed

21 files changed

+150
-4
lines changed

compiler/rustc_codegen_gcc/example/alloc_system.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
const MIN_ALIGN: usize = 8;
1616
#[cfg(any(target_arch = "x86_64",
1717
target_arch = "aarch64",
18+
target_arch = "loongarch64",
1819
target_arch = "mips64",
1920
target_arch = "s390x",
2021
target_arch = "sparc64"))]

compiler/rustc_codegen_ssa/src/back/metadata.rs

+5
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
127127
"msp430" => Architecture::Msp430,
128128
"hexagon" => Architecture::Hexagon,
129129
"bpf" => Architecture::Bpf,
130+
"loongarch64" => Architecture::LoongArch64,
130131
// Unsupported architecture.
131132
_ => return None,
132133
};
@@ -190,6 +191,10 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
190191
}
191192
e_flags
192193
}
194+
Architecture::LoongArch64 => {
195+
// Source: https://loongson.github.io/LoongArch-Documentation/LoongArch-ELF-ABI-EN.html#_e_flags_identifies_abi_type_and_version
196+
elf::EF_LARCH_OBJABI_V1 | elf::EF_LARCH_ABI_DOUBLE_FLOAT
197+
}
193198
_ => 0,
194199
};
195200
// adapted from LLVM's `MCELFObjectTargetWriter::getOSABI`

compiler/rustc_llvm/build.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const OPTIONAL_COMPONENTS: &[&str] = &[
1010
"aarch64",
1111
"amdgpu",
1212
"avr",
13+
"loongarch",
1314
"m68k",
1415
"mips",
1516
"powerpc",

compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,12 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
146146
#define SUBTARGET_HEXAGON
147147
#endif
148148

149+
#ifdef LLVM_COMPONENT_LOONGARCH
150+
#define SUBTARGET_LOONGARCH SUBTARGET(LoongArch)
151+
#else
152+
#define SUBTARGET_LOONGARCH
153+
#endif
154+
149155
#define GEN_SUBTARGETS \
150156
SUBTARGET_X86 \
151157
SUBTARGET_ARM \
@@ -159,6 +165,7 @@ extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
159165
SUBTARGET_SPARC \
160166
SUBTARGET_HEXAGON \
161167
SUBTARGET_RISCV \
168+
SUBTARGET_LOONGARCH \
162169

163170
#define SUBTARGET(x) \
164171
namespace llvm { \

compiler/rustc_llvm/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,14 @@ pub fn initialize_available_targets() {
102102
LLVMInitializeM68kAsmPrinter,
103103
LLVMInitializeM68kAsmParser
104104
);
105+
init_target!(
106+
llvm_component = "loongarch",
107+
LLVMInitializeLoongArchTargetInfo,
108+
LLVMInitializeLoongArchTarget,
109+
LLVMInitializeLoongArchTargetMC,
110+
LLVMInitializeLoongArchAsmPrinter,
111+
LLVMInitializeLoongArchAsmParser
112+
);
105113
init_target!(
106114
llvm_component = "mips",
107115
LLVMInitializeMipsTargetInfo,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
use crate::spec::{Target, TargetOptions};
2+
3+
pub fn target() -> Target {
4+
Target {
5+
llvm_target: "loongarch64-unknown-linux-gnu".into(),
6+
pointer_width: 64,
7+
data_layout: "e-m:e-p:64:64-i64:64-i128:128-n64-S128".into(),
8+
arch: "loongarch64".into(),
9+
options: TargetOptions {
10+
cpu: "generic".into(),
11+
features: "+f,+d".into(),
12+
llvm_abiname: "lp64d".into(),
13+
max_atomic_width: Some(64),
14+
..super::linux_gnu_base::opts()
15+
},
16+
}
17+
}

compiler/rustc_target/src/spec/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1021,6 +1021,7 @@ supported_targets! {
10211021
("x86_64-unknown-linux-gnux32", x86_64_unknown_linux_gnux32),
10221022
("i686-unknown-linux-gnu", i686_unknown_linux_gnu),
10231023
("i586-unknown-linux-gnu", i586_unknown_linux_gnu),
1024+
("loongarch64-unknown-linux-gnu", loongarch64_unknown_linux_gnu),
10241025
("m68k-unknown-linux-gnu", m68k_unknown_linux_gnu),
10251026
("mips-unknown-linux-gnu", mips_unknown_linux_gnu),
10261027
("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64),

config.example.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ changelog-seen = 2
8888
# the resulting rustc being unable to compile for the disabled architectures.
8989
#
9090
# To add support for new targets, see https://rustc-dev-guide.rust-lang.org/building/new-target.html.
91-
#targets = "AArch64;ARM;BPF;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86"
91+
#targets = "AArch64;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;Sparc;SystemZ;WebAssembly;X86"
9292

9393
# LLVM experimental targets to build support for. These targets are specified in
9494
# the same format as above, but since these targets are experimental, they are

library/std/src/env.rs

+1
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,7 @@ pub mod consts {
895895
/// - x86_64
896896
/// - arm
897897
/// - aarch64
898+
/// - loongarch64
898899
/// - m68k
899900
/// - mips
900901
/// - mips64

library/std/src/os/linux/raw.rs

+1
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ mod arch {
231231
}
232232

233233
#[cfg(any(
234+
target_arch = "loongarch64",
234235
target_arch = "mips64",
235236
target_arch = "s390x",
236237
target_arch = "sparc64",

library/std/src/personality/gcc.rs

+3
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ const UNWIND_DATA_REG: (i32, i32) = (0, 1); // R0, R1
7777
#[cfg(any(target_arch = "riscv64", target_arch = "riscv32"))]
7878
const UNWIND_DATA_REG: (i32, i32) = (10, 11); // x10, x11
7979

80+
#[cfg(target_arch = "loongarch64")]
81+
const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1
82+
8083
// The following code is based on GCC's C and C++ personality routines. For reference, see:
8184
// https://github.com/gcc-mirror/gcc/blob/master/libstdc++-v3/libsupc++/eh_personality.cc
8285
// https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c

library/std/src/sys/common/alloc.rs

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub const MIN_ALIGN: usize = 8;
2222
#[cfg(any(
2323
target_arch = "x86_64",
2424
target_arch = "aarch64",
25+
target_arch = "loongarch64",
2526
target_arch = "mips64",
2627
target_arch = "s390x",
2728
target_arch = "sparc64",

library/unwind/src/libunwind.rs

+3
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ pub const unwinder_private_data_size: usize = 20;
7575
#[cfg(all(target_arch = "hexagon", target_os = "linux"))]
7676
pub const unwinder_private_data_size: usize = 35;
7777

78+
#[cfg(target_arch = "loongarch64")]
79+
pub const unwinder_private_data_size: usize = 2;
80+
7881
#[repr(C)]
7982
pub struct _Unwind_Exception {
8083
pub exception_class: _Unwind_Exception_Class,

src/bootstrap/bootstrap.py

+1
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ def default_build_triple(verbose):
304304
'i486': 'i686',
305305
'i686': 'i686',
306306
'i786': 'i686',
307+
'loongarch64': 'loongarch64',
307308
'm68k': 'm68k',
308309
'powerpc': 'powerpc',
309310
'powerpc64': 'powerpc64',

src/bootstrap/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
129129
/* Extra values not defined in the built-in targets yet, but used in std */
130130
(Some(Mode::Std), "target_env", Some(&["libnx"])),
131131
// (Some(Mode::Std), "target_os", Some(&[])),
132-
(Some(Mode::Std), "target_arch", Some(&["asmjs", "spirv", "nvptx", "xtensa"])),
132+
// #[cfg(bootstrap)] loongarch64
133+
(Some(Mode::Std), "target_arch", Some(&["asmjs", "spirv", "nvptx", "xtensa", "loongarch64"])),
133134
/* Extra names used by dependencies */
134135
// FIXME: Used by serde_json, but we should not be triggering on external dependencies.
135136
(Some(Mode::Rustc), "no_btreemap_remove_entry", None),

src/bootstrap/llvm.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ impl Step for Llvm {
291291
let llvm_targets = match &builder.config.llvm_targets {
292292
Some(s) => s,
293293
None => {
294-
"AArch64;ARM;BPF;Hexagon;MSP430;Mips;NVPTX;PowerPC;RISCV;\
294+
"AArch64;ARM;BPF;Hexagon;LoongArch;MSP430;Mips;NVPTX;PowerPC;RISCV;\
295295
Sparc;SystemZ;WebAssembly;X86"
296296
}
297297
};

src/doc/rustc/src/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
- [\*-linux-ohos](platform-support/openharmony.md)
3030
- [\*-unknown-fuchsia](platform-support/fuchsia.md)
3131
- [\*-kmc-solid_\*](platform-support/kmc-solid.md)
32+
- [loongarch\*-unknown-linux-\*](platform-support/loongarch-linux.md)
3233
- [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md)
3334
- [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md)
3435
- [mipsel-sony-psx](platform-support/mipsel-sony-psx.md)

src/doc/rustc/src/platform-support.md

+1
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ target | std | host | notes
266266
`i686-uwp-windows-gnu` | ? | |
267267
`i686-uwp-windows-msvc` | ? | |
268268
`i686-wrs-vxworks` | ? | |
269+
[`loongarch64-unknown-linux-gnu`](platform-support/loongarch-linux.md) | ? | | LoongArch64 Linux (LP64D ABI)
269270
[`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? | | Motorola 680x0 Linux
270271
`mips-unknown-linux-uclibc` | ✓ | | MIPS Linux with uClibc
271272
[`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? | | MIPS64 for OpenWrt Linux MUSL
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
# loongarch\*-unknown-linux-\*
2+
3+
**Tier: 3**
4+
5+
[LoongArch] is a new RISC ISA developed by Loongson Technology Corporation Limited.
6+
7+
[LoongArch]: https://loongson.github.io/LoongArch-Documentation/README-EN.html
8+
9+
The target name follow this format: `<machine>-<vendor>-<os><fabi_suffix>, where `<machine>` specifies the CPU family/model, `<vendor>` specifies the vendor and `<os>` the operating system name.
10+
While the integer base ABI is implied by the machine field, the floating point base ABI type is encoded into the os field of the specifier using the string suffix `<fabi-suffix>`.
11+
12+
| `<fabi-suffix>` | `Description` |
13+
|------------------------|--------------------------------------------------------------------|
14+
| f64 | The base ABI use 64-bits FPRs for parameter passing.(lp64d)|
15+
| f32 | The base ABI uses 32-bit FPRs for parameter passing. (lp64f)|
16+
| sf | The base ABI uses no FPR for parameter passing. (lp64s) |
17+
18+
|`ABI type(Base ABI/ABI extension)`| `C library` | `kernel` | `target tuple` |
19+
|----------------------------------|-------------|----------|----------------------------------|
20+
| lp64d/base | glibc | linux | loongarch64-unknown-linux-gnu |
21+
| lp64f/base | glibc | linux | loongarch64-unknown-linux-gnuf32 |
22+
| lp64s/base | glibc | linux | loongarch64-unknown-linux-gnusf |
23+
| lp64d/base | musl libc | linux | loongarch64-unknown-linux-musl|
24+
| lp64f/base | musl libc | linux | loongarch64-unknown-linux-muslf32|
25+
| lp64s/base | musl libc | linux | loongarch64-unknown-linux-muslsf |
26+
27+
## Target maintainers
28+
29+
- [ZHAI xiaojuan](https://github.com/zhaixiaojuan) `[email protected]`
30+
- [WANG rui](https://github.com/heiher) `[email protected]`
31+
- [ZHAI xiang](https://github.com/xiangzhai) `[email protected]`
32+
- [WANG Xuerui](https://github.com/xen0n) `[email protected]`
33+
34+
## Requirements
35+
36+
This target is cross-compiled.
37+
A GNU toolchain for LoongArch target is required. It can be downloaded from https://github.com/loongson/build-tools/releases, or built from the source code of GCC (12.1.0 or later) and Binutils (2.40 or later).
38+
39+
## Building the target
40+
41+
The target can be built by enabling it for a `rustc` build.
42+
43+
```toml
44+
[build]
45+
target = ["loongarch64-unknown-linux-gnu"]
46+
```
47+
48+
Make sure `loongarch64-unknown-linux-gnu-gcc` can be searched from the directories specified in`$PATH`. Alternatively, you can use GNU LoongArch Toolchain by adding the following to `config.toml`:
49+
50+
```toml
51+
[target.loongarch64-unknown-linux-gnu]
52+
# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN
53+
cc = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc"
54+
cxx = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-g++"
55+
ar = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-ar"
56+
ranlib = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-ranlib"
57+
linker = "/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc"
58+
```
59+
60+
## Cross-compilation
61+
62+
This target can be cross-compiled on a `x86_64-unknown-linux-gnu` host. Cross-compilation on other hosts may work but is not tested.
63+
64+
## Testing
65+
To test a cross-compiled binary on your build system, install the qemu binary that supports the LoongArch architecture and execute the following commands.
66+
```text
67+
CC_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \
68+
CXX_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-g++ \
69+
AR_loongarch64_unknown_linux_gnu=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc-ar \
70+
CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_LINKER=/TOOLCHAIN_PATH/bin/loongarch64-unknown-linux-gnu-gcc \
71+
# SET TARGET SYSTEM LIBRARY PATH
72+
CARGO_TARGET_LOONGARCH64_UNKNOWN_LINUX_GNUN_RUNNER="qemu-loongarch64 -L /TOOLCHAIN_PATH/TARGET_LIBRAY_PATH" \
73+
cargo run --target loongarch64-unknown-linux-gnu --release
74+
```
75+
Tested on x86 architecture, other architectures not tested.
76+
77+
## Building Rust programs
78+
79+
Rust does not yet ship pre-compiled artifacts for this target. To compile for this target, you will either need to build Rust with the target enabled (see "Building the target" above), or build your own copy of `std` by using `build-std` or similar.
80+
81+
If `rustc` has support for that target and the library artifacts are available, then Rust static libraries can be built for that target:
82+
83+
```shell
84+
$ rustc --target loongarch64-unknown-linux-gnu your-code.rs --crate-type staticlib
85+
$ ls libyour_code.a
86+
```
87+
88+
On Rust Nightly it's possible to build without the target artifacts available:
89+
90+
```text
91+
cargo build -Z build-std --target loongarch64-unknown-linux-gnu
92+
```

src/librustdoc/clean/cfg.rs

+1
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,7 @@ impl<'a> fmt::Display for Display<'a> {
517517
"aarch64" => "AArch64",
518518
"arm" => "ARM",
519519
"asmjs" => "JavaScript",
520+
"loongarch64" => "LoongArch LA64",
520521
"m68k" => "M68k",
521522
"mips" => "MIPS",
522523
"mips64" => "MIPS-64",

tests/ui/check-cfg/compact-values.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ warning: unexpected `cfg` condition value
44
LL | #[cfg(target(os = "linux", arch = "X"))]
55
| ^^^^^^^^^^
66
|
7-
= note: expected values for `target_arch` are: aarch64, arm, avr, bpf, hexagon, m68k, mips, mips64, msp430, nvptx64, powerpc, powerpc64, riscv32, riscv64, s390x, sparc, sparc64, wasm32, wasm64, x86, x86_64
7+
= note: expected values for `target_arch` are: aarch64, arm, avr, bpf, hexagon, loongarch64, m68k, mips, mips64, msp430, nvptx64, powerpc, powerpc64, riscv32, riscv64, s390x, sparc, sparc64, wasm32, wasm64, x86, x86_64
88
= note: `#[warn(unexpected_cfgs)]` on by default
99

1010
warning: 1 warning emitted

0 commit comments

Comments
 (0)