diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index 4d7db96cc82..ca9fd76a997 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -261,7 +261,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> { InlineAsmArch::M68k => { constraints.push("~{ccr}".to_string()); } - InlineAsmArch::CSKY => {} // https://github.com/llvm/llvm-project/blob/8b76aea8d8b1b71f6220bc2845abc749f18a19b7/clang/lib/Basic/Targets/CSKY.h getClobers() + InlineAsmArch::CSKY => {} } } if !options.contains(InlineAsmOptions::NOMEM) { diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index f1571dd2219..baf6b19d3f9 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -297,14 +297,50 @@ const WASM_ALLOWED_FEATURES: &[(&str, Option)] = &[ const BPF_ALLOWED_FEATURES: &[(&str, Option)] = &[("alu32", Some(sym::bpf_target_feature))]; const CSKY_ALLOWED_FEATURES: &[(&str, Option)] = &[ + // tidy-alphabetical-start + ("10e60", Some(sym::csky_target_feature)), + ("2e3", Some(sym::csky_target_feature)), + ("3e3r1", Some(sym::csky_target_feature)), + ("3e3r2", Some(sym::csky_target_feature)), + ("3e3r3", Some(sym::csky_target_feature)), + ("3e7", Some(sym::csky_target_feature)), + ("7e10", Some(sym::csky_target_feature)), + ("cache", Some(sym::csky_target_feature)), + ("doloop", Some(sym::csky_target_feature)), + ("dsp1e2", Some(sym::csky_target_feature)), + ("dspe60", Some(sym::csky_target_feature)), + ("e1", Some(sym::csky_target_feature)), + ("e2", Some(sym::csky_target_feature)), + ("edsp", Some(sym::csky_target_feature)), + ("elrw", Some(sym::csky_target_feature)), + ("float1e2", Some(sym::csky_target_feature)), + ("float1e3", Some(sym::csky_target_feature)), + ("float3e4", Some(sym::csky_target_feature)), + ("float7e60", Some(sym::csky_target_feature)), + ("floate1", Some(sym::csky_target_feature)), + ("hard-tp", Some(sym::csky_target_feature)), + ("high-registers", Some(sym::csky_target_feature)), + ("hwdiv", Some(sym::csky_target_feature)), + ("mp", Some(sym::csky_target_feature)), + ("mp1e2", Some(sym::csky_target_feature)), + ("nvic", Some(sym::csky_target_feature)), + ("trust", Some(sym::csky_target_feature)), + ("vdsp2e60f", Some(sym::csky_target_feature)), + ("vdspv1", Some(sym::csky_target_feature)), + ("vdspv2", Some(sym::csky_target_feature)), + // tidy-alphabetical-end + //fpu + // tidy-alphabetical-start + ("fdivdu", Some(sym::csky_target_feature)), + ("fpuv2_df", Some(sym::csky_target_feature)), + ("fpuv2_sf", Some(sym::csky_target_feature)), + ("fpuv3_df", Some(sym::csky_target_feature)), + ("fpuv3_hf", Some(sym::csky_target_feature)), + ("fpuv3_hi", Some(sym::csky_target_feature)), + ("fpuv3_sf", Some(sym::csky_target_feature)), ("hard-float", Some(sym::csky_target_feature)), ("hard-float-abi", Some(sym::csky_target_feature)), - ("fpuv2_sf", Some(sym::csky_target_feature)), - ("fpuv2_df", Some(sym::csky_target_feature)), - ("fpuv3_sf", Some(sym::csky_target_feature)), - ("fpuv3_df", Some(sym::csky_target_feature)), - ("vdspv2", Some(sym::csky_target_feature)), - ("dspv2", Some(sym::csky_target_feature)), + // tidy-alphabetical-end ]; /// When rustdoc is running, provide a list of all known features so that all their respective /// primitives may be documented. diff --git a/compiler/rustc_target/src/asm/csky.rs b/compiler/rustc_target/src/asm/csky.rs index 13bb846c731..6f0e7f79949 100644 --- a/compiler/rustc_target/src/asm/csky.rs +++ b/compiler/rustc_target/src/asm/csky.rs @@ -36,8 +36,8 @@ impl CSKYInlineAsmRegClass { _arch: InlineAsmArch, ) -> &'static [(InlineAsmType, Option)] { match self { - Self::reg => types! { _: I8, I16, I32, I64, F32, F64; }, - Self::freg => types! { _: F32, F64; }, + Self::reg => types! { _: I8, I16, I32; }, + Self::freg => types! { _: F32; }, } } } @@ -52,31 +52,21 @@ def_regs! { r4: reg = ["r4","l0"], r5: reg = ["r5","l1"], r6: reg = ["r6","l2"], - // r7: reg = ["r7","l3"], - // r8: reg = ["r8","l4"], - // r9: reg = ["r9","l5"], - // r10: reg = ["r10","l6"], - // r11: reg = ["r11","l7"], - // r12: reg = ["r12","t0"], - // r13: reg = ["r13","t1"], - // r14: reg = ["r14","sp"], - // r15: reg = ["r15","lr"], - // r16: reg = ["r16","l8"], - // r17: reg = ["r17","l9"], - // r18: reg = ["r18","t2"], - // r19: reg = ["r19","t3"], - // r20: reg = ["r20","t4"], - // r21: reg = ["r21","t5"], - // r22: reg = ["r22","t6"], - // r23: reg = ["r23","t7", "fp"], - // r24: reg = ["r24","t8", "sop"], - // r25: reg = ["r25","tp", "bsp"], - // r26: reg = ["r26"], - // r27: reg = ["r27"], - // r28: reg = ["r28","gb", "rgb", "rdb"], - // r29: reg = ["r29","tb", "rtb"], - // r30: reg = ["r30","svbr"], - // r31: reg = ["r31","tls"], + r9: reg = ["r9","l5"],// feature e2 + r10: reg = ["r10","l6"],// feature e2 + r11: reg = ["r11","l7"],// feature e2 + r12: reg = ["r12","t0"],// feature e2 + r13: reg = ["r13","t1"],// feature e2 + r16: reg = ["r16","l8"],// feature high-register + r17: reg = ["r17","l9"],// feature high-register + r18: reg = ["r18","t2"],// feature high-register + r19: reg = ["r19","t3"],// feature high-register + r20: reg = ["r20","t4"],// feature high-register + r21: reg = ["r21","t5"],// feature high-register + r22: reg = ["r22","t6"],// feature high-register + r23: reg = ["r23","t7", "fp"],// feature high-register + r24: reg = ["r24","t8", "sop"],// feature high-register + r25: reg = ["r25","t9","tp", "bsp"],// feature high-register f0: freg = ["fr0","vr0"], f1: freg = ["fr1","vr1"], f2: freg = ["fr2","vr2"], @@ -121,10 +111,6 @@ def_regs! { "reserver for tls", #error = ["r28", "gb", "rgb", "rdb"] => "the global pointer cannot be used as an operand for inline asm", - #error = ["r9","l5", "r10","l6", "r11","l7", "r12","t0", "r13","t1"] => - "reserved (no E2)", - #error = ["r16","l8", "r17","l9", "r18","t2", "r19","t3", "r20","t4", "r21","t5", "r22","t6", "r23","t7", "fp", "r24","t8", "sop", "r25","tp", "bsp"] => - "reserved (no HighRegisters)", #error = ["r26","r27","r29","tb", "rtb", "r30","svbr"] => "reserved by the ABI", } diff --git a/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs b/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs index 3bc075f6920..7d03dd26f5d 100644 --- a/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs +++ b/compiler/rustc_target/src/spec/csky_unknown_linux_gnuabiv2.rs @@ -1,7 +1,6 @@ -use crate::spec::{Target, TargetOptions}; +use crate::spec::{Cc, LinkerFlavor, Lld, Target, TargetOptions}; // This target is for glibc Linux on Csky -// hardfloat. pub fn target() -> Target { Target { @@ -12,10 +11,9 @@ pub fn target() -> Target { arch: "csky".into(), options: TargetOptions { abi: "abiv2".into(), - //+hard-float, +hard-float-abi, +fpuv2_sf, +fpuv2_df, +fpuv3_sf, +fpuv3_df, +vdspv2, +dspv2, +vdspv1, +3e3r1 - features: "".into(), + features: "+2e3,+3e7,+7e10,+cache,+dsp1e2,+dspe60,+e1,+e2,+edsp,+elrw,+hard-tp,+high-registers,+hwdiv,+mp,+mp1e2,+nvic,+trust".into(), + late_link_args_static: TargetOptions::link_args(LinkerFlavor::Gnu(Cc::Yes, Lld::No), &["-l:libatomic.a"]), max_atomic_width: Some(32), - // mcount: "\u{1}__gnu_mcount_nc".into(), ..super::linux_gnu_base::opts() }, } diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs index 7acf657f630..da7ff626cb2 100644 --- a/src/bootstrap/llvm.rs +++ b/src/bootstrap/llvm.rs @@ -390,6 +390,22 @@ impl Step for Llvm { ldflags.shared.push(" -latomic"); } + if target.starts_with("csky") + && !target.contains("freebsd") + && !target.contains("openbsd") + && !target.contains("netbsd") + { + // CSKY GCC erroneously requires linking against + // `libatomic` when using 1-byte and 2-byte C++ + // atomics but the LLVM build system check cannot + // detect this. Therefore it is set manually here. + // Some BSD uses Clang as its system compiler and + // provides no libatomic in its base system so does + // not want this. + ldflags.exe.push(" -latomic"); + ldflags.shared.push(" -latomic"); + } + if target.contains("msvc") { cfg.define("LLVM_USE_CRT_DEBUG", "MT"); cfg.define("LLVM_USE_CRT_RELEASE", "MT"); diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index a78b5314fcc..371ee378d1a 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -259,7 +259,7 @@ target | std | host | notes `avr-unknown-gnu-atmega328` | * | | AVR. Requires `-Z build-std=core` `bpfeb-unknown-none` | * | | BPF (big endian) `bpfel-unknown-none` | * | | BPF (little endian) -`csky-unknown-linux-gnuabiv2` | ? | | C-SKY iv2 Linux +`csky-unknown-linux-gnuabiv2` | ✓ | | C-SKY abiv2 Linux(little endian) `hexagon-unknown-linux-musl` | ? | | `i386-apple-ios` | ✓ | | 32-bit x86 iOS [`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * | | 32-bit x86 QNX Neutrino 7.0 RTOS | diff --git a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md index 240d58596cf..e73598be0d9 100644 --- a/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md +++ b/src/doc/rustc/src/platform-support/csky-unknown-linux-gnuabiv2.md @@ -5,6 +5,8 @@ This target supports [C-SKY](https://github.com/c-sky) CPUs with `abi` v2 and `glibc`. https://c-sky.github.io/ +https://gitlab.com/c-sky/ + ## Target maintainers * [@Dirreke](https://github.com/Dirreke) @@ -14,20 +16,55 @@ https://c-sky.github.io/ ## Building the target -add `csky-unknown-linux-gnuabiv2` to the `target` list in `config.toml` and `./x build`. +### Get a C toolchain -## Building Rust programs +Compiling rust for this target has been tested on `x86_64` linux hosts. Other host types have not been tested, but may work, if you can find a suitable cross compilation toolchain for them. -Rust programs can be built for that target: +If you don't already have a suitable toolchain, you can download from [here](https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource/1356021/1619528643136/csky-linux-gnuabiv2-tools-x86_64-glibc-linux-4.9.56-20210423.tar.gz), and unpack it into a directory. -```text -cargo +stage2 --target csky-unknown-linux-gnuabiv2 your-code.rs +### Configure rust + +The target can be built by enabling it for a `rustc` build, by placing the following in `config.toml`: + +```toml +[build] +target = ["x86_64-unknown-linux-gnu", "csky-unknown-linux-gnuabiv2"] +stage = 2 + +[target.csky-unknown-linux-gnuabiv2] +# ADJUST THIS PATH TO POINT AT YOUR TOOLCHAIN +cc = "${TOOLCHAIN_PATH}/bin/csky-linux-gnuabiv2-gcc" + +### Build + +```sh +# in rust dir +./x.py build --stage 2 ``` -## Testing +## Building and Running Rust programs -Currently there is no support to run the rustc test suite for this target. +To test cross-compiled binaries on a `x86_64` system, you can use the `qemu-cskyv2`. This avoids having a full emulated ARM system by doing dynamic binary translation and dynamic system call translation. It lets you run CSKY programs directly on your `x86_64` kernel. It's very convenient! -## Cross-compilation toolchains and C code +To use: -This target can be cross-compiled from `x86_64` on either Linux systems with [`csky-linux-gunabiv2-tools-x86_64-glibc-linux`](https://github.com/c-sky/toolchain-build). +* Install `qemu-cskyv2` (If you don't already have a qemu, you can download from [here](https://occ-oss-prod.oss-cn-hangzhou.aliyuncs.com/resource//1689324918932/xuantie-qemu-x86_64-Ubuntu-18.04-20230714-0202.tar.gz"), and unpack it into a directory.) +* Link your built toolchain via: + * `rustup toolchain link stage2 ${RUST}/build/x86_64-unknown-linux-gnu/stage2` +* Create a test program + +```sh +cargo new hello_world +cd hello_world +``` + +* Build and run + +```sh +CARGO_TARGET_CSKY_UNKNOWN_LINUX_GNUABIV2_RUNNER=${QEMU_PATH}/bin/qemu-cskyv2 -L ${TOOLCHAIN_PATH}/csky-linux-gnuabiv2/libc \ +CARGO_TARGET_CSKY_UNKNOWN_LINUX_GNUABIV2_LINKER=${TOOLCHAIN_PATH}/bin/csky-linux-gnuabiv2-gcc \ +RUSTFLAGS="-C target-features=+crt-static" \ +cargo +stage2 run --target csky-unknown-linux-gnuabiv2 +``` + +Attention: The dynamic-linked program may nor be run by `qemu-cskyv2` but can be run on the target. diff --git a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md index d52287051c6..968c9bb4ebb 100644 --- a/src/doc/unstable-book/src/language-features/asm-experimental-arch.md +++ b/src/doc/unstable-book/src/language-features/asm-experimental-arch.md @@ -82,8 +82,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | MSP430 | `reg` | None | `i8`, `i16` | | M68k | `reg`, `reg_addr` | None | `i16`, `i32` | | M68k | `reg_data` | None | `i8`, `i16`, `i32` | -| CSKY | `reg` | None | `i8`, `i16`, `i32`, `i64` | -| CSKY | `freg` | None | `f32`, `f64` | +| CSKY | `reg` | None | `i8`, `i16`, `i32` | +| CSKY | `freg` | None | `f32`, | | s390x | `reg` | None | `i8`, `i16`, `i32`, `i64` | | s390x | `freg` | None | `f32`, `f64` | @@ -107,9 +107,16 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | M68k | `a5` | `bp` | | M68k | `a6` | `fp` | | M68k | `a7` | `sp`, `usp`, `ssp`, `isp` | +| CSKY | `r[0-3]` | `a[0-3]` | +| CSKY | `r[4-11]` | `l[0-7]` | +| CSKY | `r[12-13]` | `t[0-1]` | | CSKY | `r14` | `sp` | | CSKY | `r15` | `lr` | -| CSKY | `r28` | `gb`, `rgb`, `rdb` | +| CSKY | `r[16-17]` | `l[8-9]` | +| CSKY | `r[18-25]` | `t[2-9]` | +| CSKY | `r28` | `rgb` | +| CSKY | `r29` | `rtb` | +| CSKY | `r30` | `svbr` | | CSKY | `r31` | `tls` | > **Notes**: @@ -132,6 +139,13 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | AVR | `r0`, `r1`, `r1r0` | Due to an issue in LLVM, the `r0` and `r1` registers cannot be used as inputs or outputs. If modified, they must be restored to their original values before the end of the block. | |MSP430 | `r0`, `r2`, `r3` | These are the program counter, status register, and constant generator respectively. Neither the status register nor constant generator can be written to. | | M68k | `a4`, `a5` | Used internally by LLVM for the base pointer and global base pointer. | +| CSKY | `r7`, `r28` | Used internally by LLVM for the base pointer and global base pointer. | +| CSKY | `r8` | Used internally by LLVM for the frame pointer. | +| CSKY | `r14` | Used internally by LLVM for the stack pointer. | +| CSKY | `r15` | This is the link register. | +| CSKY | `r[26-30]` | Reserved by its ABI. | +| CSKY | `r31` | This is the TLS register. | + ## Template modifiers @@ -148,6 +162,8 @@ This feature tracks `asm!` and `global_asm!` support for the following architect | PowerPC | `freg` | None | `0` | None | | s390x | `reg` | None | `%r0` | None | | s390x | `freg` | None | `%f0` | None | +| CSKY | `reg` | None | `r0` | None | +| CSKY | `freg` | None | `f0` | None | # Flags covered by `preserves_flags`