From 4a5b4444b786e57e3f45dc554f325d6fa6df92ef Mon Sep 17 00:00:00 2001 From: WANG Rui Date: Sat, 28 Jun 2025 11:16:39 +0800 Subject: [PATCH] loongarch: Add basic support for LoongArch32 --- crates/core_arch/src/core_arch_docs.md | 2 + crates/core_arch/src/loongarch32/mod.rs | 47 ++++ crates/core_arch/src/loongarch64/mod.rs | 239 +---------------- crates/core_arch/src/loongarch_shared/mod.rs | 244 ++++++++++++++++++ crates/core_arch/src/mod.rs | 21 +- crates/simd-test-macro/src/lib.rs | 2 +- crates/std_detect/README.md | 2 +- .../std_detect/src/detect/arch/loongarch.rs | 2 +- crates/std_detect/src/detect/arch/mod.rs | 2 +- crates/std_detect/src/detect/mod.rs | 1 + .../std_detect/src/detect/os/linux/auxvec.rs | 2 + crates/std_detect/src/detect/os/linux/mod.rs | 2 +- .../std_detect/tests/macro_trailing_commas.rs | 8 +- 13 files changed, 327 insertions(+), 247 deletions(-) create mode 100644 crates/core_arch/src/loongarch32/mod.rs create mode 100644 crates/core_arch/src/loongarch_shared/mod.rs diff --git a/crates/core_arch/src/core_arch_docs.md b/crates/core_arch/src/core_arch_docs.md index bfa1b72288..6aea2b4618 100644 --- a/crates/core_arch/src/core_arch_docs.md +++ b/crates/core_arch/src/core_arch_docs.md @@ -193,6 +193,7 @@ others at: * [`powerpc64`] * [`nvptx`] * [`wasm32`] +* [`loongarch32`] * [`loongarch64`] * [`s390x`] @@ -208,6 +209,7 @@ others at: [`powerpc64`]: ../../core/arch/powerpc64/index.html [`nvptx`]: ../../core/arch/nvptx/index.html [`wasm32`]: ../../core/arch/wasm32/index.html +[`loongarch32`]: ../../core/arch/loongarch32/index.html [`loongarch64`]: ../../core/arch/loongarch64/index.html [`s390x`]: ../../core/arch/s390x/index.html diff --git a/crates/core_arch/src/loongarch32/mod.rs b/crates/core_arch/src/loongarch32/mod.rs new file mode 100644 index 0000000000..fb05450373 --- /dev/null +++ b/crates/core_arch/src/loongarch32/mod.rs @@ -0,0 +1,47 @@ +//! `LoongArch32` intrinsics + +use crate::arch::asm; + +#[allow(improper_ctypes)] +unsafe extern "unadjusted" { + #[link_name = "llvm.loongarch.cacop.w"] + fn __cacop(a: i32, b: i32, c: i32); + #[link_name = "llvm.loongarch.csrrd.w"] + fn __csrrd(a: i32) -> i32; + #[link_name = "llvm.loongarch.csrwr.w"] + fn __csrwr(a: i32, b: i32) -> i32; + #[link_name = "llvm.loongarch.csrxchg.w"] + fn __csrxchg(a: i32, b: i32, c: i32) -> i32; +} + +/// Generates the cache operation instruction +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn cacop(a: i32, b: i32) { + static_assert_simm_bits!(IMM12, 12); + __cacop(a, b, IMM12); +} + +/// Reads the CSR +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn csrrd() -> i32 { + static_assert_uimm_bits!(IMM14, 14); + __csrrd(IMM14) +} + +/// Writes the CSR +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn csrwr(a: i32) -> i32 { + static_assert_uimm_bits!(IMM14, 14); + __csrwr(a, IMM14) +} + +/// Exchanges the CSR +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn csrxchg(a: i32, b: i32) -> i32 { + static_assert_uimm_bits!(IMM14, 14); + __csrxchg(a, b, IMM14) +} diff --git a/crates/core_arch/src/loongarch64/mod.rs b/crates/core_arch/src/loongarch64/mod.rs index b1704bbb48..3f1bfbcd0e 100644 --- a/crates/core_arch/src/loongarch64/mod.rs +++ b/crates/core_arch/src/loongarch64/mod.rs @@ -1,4 +1,4 @@ -//! `LoongArch` intrinsics +//! `LoongArch64` intrinsics mod lasx; mod lsx; @@ -20,82 +20,24 @@ pub unsafe fn rdtime_d() -> (i64, isize) { (val, tid) } -/// Reads the lower 32-bit stable counter value and the counter ID -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn rdtimel_w() -> (i32, isize) { - let val: i32; - let tid: isize; - asm!("rdtimel.w {}, {}", out(reg) val, out(reg) tid, options(readonly, nostack)); - (val, tid) -} - -/// Reads the upper 32-bit stable counter value and the counter ID -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn rdtimeh_w() -> (i32, isize) { - let val: i32; - let tid: isize; - asm!("rdtimeh.w {}, {}", out(reg) val, out(reg) tid, options(readonly, nostack)); - (val, tid) -} - #[allow(improper_ctypes)] unsafe extern "unadjusted" { - #[link_name = "llvm.loongarch.crc.w.b.w"] - fn __crc_w_b_w(a: i32, b: i32) -> i32; - #[link_name = "llvm.loongarch.crc.w.h.w"] - fn __crc_w_h_w(a: i32, b: i32) -> i32; - #[link_name = "llvm.loongarch.crc.w.w.w"] - fn __crc_w_w_w(a: i32, b: i32) -> i32; #[link_name = "llvm.loongarch.crc.w.d.w"] fn __crc_w_d_w(a: i64, b: i32) -> i32; - #[link_name = "llvm.loongarch.crcc.w.b.w"] - fn __crcc_w_b_w(a: i32, b: i32) -> i32; - #[link_name = "llvm.loongarch.crcc.w.h.w"] - fn __crcc_w_h_w(a: i32, b: i32) -> i32; - #[link_name = "llvm.loongarch.crcc.w.w.w"] - fn __crcc_w_w_w(a: i32, b: i32) -> i32; #[link_name = "llvm.loongarch.crcc.w.d.w"] fn __crcc_w_d_w(a: i64, b: i32) -> i32; #[link_name = "llvm.loongarch.cacop.d"] fn __cacop(a: i64, b: i64, c: i64); - #[link_name = "llvm.loongarch.dbar"] - fn __dbar(a: i32); - #[link_name = "llvm.loongarch.ibar"] - fn __ibar(a: i32); - #[link_name = "llvm.loongarch.movgr2fcsr"] - fn __movgr2fcsr(a: i32, b: i32); - #[link_name = "llvm.loongarch.movfcsr2gr"] - fn __movfcsr2gr(a: i32) -> i32; #[link_name = "llvm.loongarch.csrrd.d"] fn __csrrd(a: i32) -> i64; #[link_name = "llvm.loongarch.csrwr.d"] fn __csrwr(a: i64, b: i32) -> i64; #[link_name = "llvm.loongarch.csrxchg.d"] fn __csrxchg(a: i64, b: i64, c: i32) -> i64; - #[link_name = "llvm.loongarch.iocsrrd.b"] - fn __iocsrrd_b(a: i32) -> i32; - #[link_name = "llvm.loongarch.iocsrrd.h"] - fn __iocsrrd_h(a: i32) -> i32; - #[link_name = "llvm.loongarch.iocsrrd.w"] - fn __iocsrrd_w(a: i32) -> i32; #[link_name = "llvm.loongarch.iocsrrd.d"] fn __iocsrrd_d(a: i32) -> i64; - #[link_name = "llvm.loongarch.iocsrwr.b"] - fn __iocsrwr_b(a: i32, b: i32); - #[link_name = "llvm.loongarch.iocsrwr.h"] - fn __iocsrwr_h(a: i32, b: i32); - #[link_name = "llvm.loongarch.iocsrwr.w"] - fn __iocsrwr_w(a: i32, b: i32); #[link_name = "llvm.loongarch.iocsrwr.d"] fn __iocsrwr_d(a: i64, b: i32); - #[link_name = "llvm.loongarch.break"] - fn __break(a: i32); - #[link_name = "llvm.loongarch.cpucfg"] - fn __cpucfg(a: i32) -> i32; - #[link_name = "llvm.loongarch.syscall"] - fn __syscall(a: i32); #[link_name = "llvm.loongarch.asrtle.d"] fn __asrtle(a: i64, b: i64); #[link_name = "llvm.loongarch.asrtgt.d"] @@ -104,35 +46,6 @@ unsafe extern "unadjusted" { fn __lddir(a: i64, b: i64) -> i64; #[link_name = "llvm.loongarch.ldpte.d"] fn __ldpte(a: i64, b: i64); - #[link_name = "llvm.loongarch.frecipe.s"] - fn __frecipe_s(a: f32) -> f32; - #[link_name = "llvm.loongarch.frecipe.d"] - fn __frecipe_d(a: f64) -> f64; - #[link_name = "llvm.loongarch.frsqrte.s"] - fn __frsqrte_s(a: f32) -> f32; - #[link_name = "llvm.loongarch.frsqrte.d"] - fn __frsqrte_d(a: f64) -> f64; -} - -/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320) -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn crc_w_b_w(a: i32, b: i32) -> i32 { - __crc_w_b_w(a, b) -} - -/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320) -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn crc_w_h_w(a: i32, b: i32) -> i32 { - __crc_w_h_w(a, b) -} - -/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320) -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn crc_w_w_w(a: i32, b: i32) -> i32 { - __crc_w_w_w(a, b) } /// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320) @@ -142,27 +55,6 @@ pub unsafe fn crc_w_d_w(a: i64, b: i32) -> i32 { __crc_w_d_w(a, b) } -/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78) -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn crcc_w_b_w(a: i32, b: i32) -> i32 { - __crcc_w_b_w(a, b) -} - -/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78) -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn crcc_w_h_w(a: i32, b: i32) -> i32 { - __crcc_w_h_w(a, b) -} - -/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78) -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn crcc_w_w_w(a: i32, b: i32) -> i32 { - __crcc_w_w_w(a, b) -} - /// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78) #[inline] #[unstable(feature = "stdarch_loongarch", issue = "117427")] @@ -178,38 +70,6 @@ pub unsafe fn cacop(a: i64, b: i64) { __cacop(a, b, IMM12); } -/// Generates the memory barrier instruction -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn dbar() { - static_assert_uimm_bits!(IMM15, 15); - __dbar(IMM15); -} - -/// Generates the instruction-fetch barrier instruction -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn ibar() { - static_assert_uimm_bits!(IMM15, 15); - __ibar(IMM15); -} - -/// Moves data from a GPR to the FCSR -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn movgr2fcsr(a: i32) { - static_assert_uimm_bits!(IMM5, 5); - __movgr2fcsr(IMM5, a); -} - -/// Moves data from a FCSR to the GPR -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn movfcsr2gr() -> i32 { - static_assert_uimm_bits!(IMM5, 5); - __movfcsr2gr(IMM5) -} - /// Reads the CSR #[inline] #[unstable(feature = "stdarch_loongarch", issue = "117427")] @@ -234,27 +94,6 @@ pub unsafe fn csrxchg(a: i64, b: i64) -> i64 { __csrxchg(a, b, IMM14) } -/// Reads the 8-bit IO-CSR -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn iocsrrd_b(a: i32) -> i32 { - __iocsrrd_b(a) -} - -/// Reads the 16-bit IO-CSR -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn iocsrrd_h(a: i32) -> i32 { - __iocsrrd_h(a) -} - -/// Reads the 32-bit IO-CSR -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn iocsrrd_w(a: i32) -> i32 { - __iocsrrd_w(a) -} - /// Reads the 64-bit IO-CSR #[inline] #[unstable(feature = "stdarch_loongarch", issue = "117427")] @@ -262,27 +101,6 @@ pub unsafe fn iocsrrd_d(a: i32) -> i64 { __iocsrrd_d(a) } -/// Writes the 8-bit IO-CSR -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn iocsrwr_b(a: i32, b: i32) { - __iocsrwr_b(a, b) -} - -/// Writes the 16-bit IO-CSR -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn iocsrwr_h(a: i32, b: i32) { - __iocsrwr_h(a, b) -} - -/// Writes the 32-bit IO-CSR -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn iocsrwr_w(a: i32, b: i32) { - __iocsrwr_w(a, b) -} - /// Writes the 64-bit IO-CSR #[inline] #[unstable(feature = "stdarch_loongarch", issue = "117427")] @@ -290,29 +108,6 @@ pub unsafe fn iocsrwr_d(a: i64, b: i32) { __iocsrwr_d(a, b) } -/// Generates the breakpoint instruction -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn brk() { - static_assert_uimm_bits!(IMM15, 15); - __break(IMM15); -} - -/// Reads the CPU configuration register -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn cpucfg(a: i32) -> i32 { - __cpucfg(a) -} - -/// Generates the syscall instruction -#[inline] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn syscall() { - static_assert_uimm_bits!(IMM15, 15); - __syscall(IMM15); -} - /// Generates the less-than-or-equal asseration instruction #[inline] #[unstable(feature = "stdarch_loongarch", issue = "117427")] @@ -342,35 +137,3 @@ pub unsafe fn lddir(a: i64) -> i64 { pub unsafe fn ldpte(a: i64) { __ldpte(a, B) } - -/// Calculate the approximate single-precision result of 1.0 divided -#[inline] -#[target_feature(enable = "frecipe")] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn frecipe_s(a: f32) -> f32 { - __frecipe_s(a) -} - -/// Calculate the approximate double-precision result of 1.0 divided -#[inline] -#[target_feature(enable = "frecipe")] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn frecipe_d(a: f64) -> f64 { - __frecipe_d(a) -} - -/// Calculate the approximate single-precision result of dividing 1.0 by the square root -#[inline] -#[target_feature(enable = "frecipe")] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn frsqrte_s(a: f32) -> f32 { - __frsqrte_s(a) -} - -/// Calculate the approximate double-precision result of dividing 1.0 by the square root -#[inline] -#[target_feature(enable = "frecipe")] -#[unstable(feature = "stdarch_loongarch", issue = "117427")] -pub unsafe fn frsqrte_d(a: f64) -> f64 { - __frsqrte_d(a) -} diff --git a/crates/core_arch/src/loongarch_shared/mod.rs b/crates/core_arch/src/loongarch_shared/mod.rs new file mode 100644 index 0000000000..da716ffd27 --- /dev/null +++ b/crates/core_arch/src/loongarch_shared/mod.rs @@ -0,0 +1,244 @@ +//! `Shared LoongArch` intrinsics + +use crate::arch::asm; + +/// Reads the lower 32-bit stable counter value and the counter ID +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn rdtimel_w() -> (i32, isize) { + let val: i32; + let tid: isize; + asm!("rdtimel.w {}, {}", out(reg) val, out(reg) tid, options(readonly, nostack)); + (val, tid) +} + +/// Reads the upper 32-bit stable counter value and the counter ID +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn rdtimeh_w() -> (i32, isize) { + let val: i32; + let tid: isize; + asm!("rdtimeh.w {}, {}", out(reg) val, out(reg) tid, options(readonly, nostack)); + (val, tid) +} + +#[allow(improper_ctypes)] +unsafe extern "unadjusted" { + #[link_name = "llvm.loongarch.crc.w.b.w"] + fn __crc_w_b_w(a: i32, b: i32) -> i32; + #[link_name = "llvm.loongarch.crc.w.h.w"] + fn __crc_w_h_w(a: i32, b: i32) -> i32; + #[link_name = "llvm.loongarch.crc.w.w.w"] + fn __crc_w_w_w(a: i32, b: i32) -> i32; + #[link_name = "llvm.loongarch.crcc.w.b.w"] + fn __crcc_w_b_w(a: i32, b: i32) -> i32; + #[link_name = "llvm.loongarch.crcc.w.h.w"] + fn __crcc_w_h_w(a: i32, b: i32) -> i32; + #[link_name = "llvm.loongarch.crcc.w.w.w"] + fn __crcc_w_w_w(a: i32, b: i32) -> i32; + #[link_name = "llvm.loongarch.dbar"] + fn __dbar(a: i32); + #[link_name = "llvm.loongarch.ibar"] + fn __ibar(a: i32); + #[link_name = "llvm.loongarch.movgr2fcsr"] + fn __movgr2fcsr(a: i32, b: i32); + #[link_name = "llvm.loongarch.movfcsr2gr"] + fn __movfcsr2gr(a: i32) -> i32; + #[link_name = "llvm.loongarch.iocsrrd.b"] + fn __iocsrrd_b(a: i32) -> i32; + #[link_name = "llvm.loongarch.iocsrrd.h"] + fn __iocsrrd_h(a: i32) -> i32; + #[link_name = "llvm.loongarch.iocsrrd.w"] + fn __iocsrrd_w(a: i32) -> i32; + #[link_name = "llvm.loongarch.iocsrwr.b"] + fn __iocsrwr_b(a: i32, b: i32); + #[link_name = "llvm.loongarch.iocsrwr.h"] + fn __iocsrwr_h(a: i32, b: i32); + #[link_name = "llvm.loongarch.iocsrwr.w"] + fn __iocsrwr_w(a: i32, b: i32); + #[link_name = "llvm.loongarch.break"] + fn __break(a: i32); + #[link_name = "llvm.loongarch.cpucfg"] + fn __cpucfg(a: i32) -> i32; + #[link_name = "llvm.loongarch.syscall"] + fn __syscall(a: i32); + #[link_name = "llvm.loongarch.frecipe.s"] + fn __frecipe_s(a: f32) -> f32; + #[link_name = "llvm.loongarch.frecipe.d"] + fn __frecipe_d(a: f64) -> f64; + #[link_name = "llvm.loongarch.frsqrte.s"] + fn __frsqrte_s(a: f32) -> f32; + #[link_name = "llvm.loongarch.frsqrte.d"] + fn __frsqrte_d(a: f64) -> f64; +} + +/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320) +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn crc_w_b_w(a: i32, b: i32) -> i32 { + __crc_w_b_w(a, b) +} + +/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320) +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn crc_w_h_w(a: i32, b: i32) -> i32 { + __crc_w_h_w(a, b) +} + +/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320) +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn crc_w_w_w(a: i32, b: i32) -> i32 { + __crc_w_w_w(a, b) +} + +/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78) +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn crcc_w_b_w(a: i32, b: i32) -> i32 { + __crcc_w_b_w(a, b) +} + +/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78) +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn crcc_w_h_w(a: i32, b: i32) -> i32 { + __crcc_w_h_w(a, b) +} + +/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78) +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn crcc_w_w_w(a: i32, b: i32) -> i32 { + __crcc_w_w_w(a, b) +} + +/// Generates the memory barrier instruction +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn dbar() { + static_assert_uimm_bits!(IMM15, 15); + __dbar(IMM15); +} + +/// Generates the instruction-fetch barrier instruction +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn ibar() { + static_assert_uimm_bits!(IMM15, 15); + __ibar(IMM15); +} + +/// Moves data from a GPR to the FCSR +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn movgr2fcsr(a: i32) { + static_assert_uimm_bits!(IMM5, 5); + __movgr2fcsr(IMM5, a); +} + +/// Moves data from a FCSR to the GPR +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn movfcsr2gr() -> i32 { + static_assert_uimm_bits!(IMM5, 5); + __movfcsr2gr(IMM5) +} + +/// Reads the 8-bit IO-CSR +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn iocsrrd_b(a: i32) -> i32 { + __iocsrrd_b(a) +} + +/// Reads the 16-bit IO-CSR +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn iocsrrd_h(a: i32) -> i32 { + __iocsrrd_h(a) +} + +/// Reads the 32-bit IO-CSR +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn iocsrrd_w(a: i32) -> i32 { + __iocsrrd_w(a) +} + +/// Writes the 8-bit IO-CSR +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn iocsrwr_b(a: i32, b: i32) { + __iocsrwr_b(a, b) +} + +/// Writes the 16-bit IO-CSR +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn iocsrwr_h(a: i32, b: i32) { + __iocsrwr_h(a, b) +} + +/// Writes the 32-bit IO-CSR +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn iocsrwr_w(a: i32, b: i32) { + __iocsrwr_w(a, b) +} + +/// Generates the breakpoint instruction +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn brk() { + static_assert_uimm_bits!(IMM15, 15); + __break(IMM15); +} + +/// Reads the CPU configuration register +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn cpucfg(a: i32) -> i32 { + __cpucfg(a) +} + +/// Generates the syscall instruction +#[inline] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn syscall() { + static_assert_uimm_bits!(IMM15, 15); + __syscall(IMM15); +} + +/// Calculate the approximate single-precision result of 1.0 divided +#[inline] +#[target_feature(enable = "frecipe")] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn frecipe_s(a: f32) -> f32 { + __frecipe_s(a) +} + +/// Calculate the approximate double-precision result of 1.0 divided +#[inline] +#[target_feature(enable = "frecipe")] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn frecipe_d(a: f64) -> f64 { + __frecipe_d(a) +} + +/// Calculate the approximate single-precision result of dividing 1.0 by the square root +#[inline] +#[target_feature(enable = "frecipe")] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn frsqrte_s(a: f32) -> f32 { + __frsqrte_s(a) +} + +/// Calculate the approximate double-precision result of dividing 1.0 by the square root +#[inline] +#[target_feature(enable = "frecipe")] +#[unstable(feature = "stdarch_loongarch", issue = "117427")] +pub unsafe fn frsqrte_d(a: f64) -> f64 { + __frsqrte_d(a) +} diff --git a/crates/core_arch/src/mod.rs b/crates/core_arch/src/mod.rs index f6e959efd4..2105cca1b4 100644 --- a/crates/core_arch/src/mod.rs +++ b/crates/core_arch/src/mod.rs @@ -16,6 +16,9 @@ mod riscv_shared; ))] mod arm_shared; +#[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64", doc))] +mod loongarch_shared; + mod simd; #[doc = include_str!("core_arch_docs.md")] @@ -271,13 +274,25 @@ pub mod arch { pub use crate::core_arch::nvptx::*; } - /// Platform-specific intrinsics for the `loongarch` platform. + /// Platform-specific intrinsics for the `loongarch32` platform. + /// + /// See the [module documentation](../index.html) for more details. + #[cfg(any(target_arch = "loongarch32", doc))] + #[doc(cfg(target_arch = "loongarch32"))] + #[unstable(feature = "stdarch_loongarch", issue = "117427")] + pub mod loongarch32 { + pub use crate::core_arch::loongarch_shared::*; + pub use crate::core_arch::loongarch32::*; + } + + /// Platform-specific intrinsics for the `loongarch64` platform. /// /// See the [module documentation](../index.html) for more details. #[cfg(any(target_arch = "loongarch64", doc))] #[doc(cfg(target_arch = "loongarch64"))] #[unstable(feature = "stdarch_loongarch", issue = "117427")] pub mod loongarch64 { + pub use crate::core_arch::loongarch_shared::*; pub use crate::core_arch::loongarch64::*; } @@ -334,6 +349,10 @@ mod powerpc64; #[doc(cfg(target_arch = "nvptx64"))] mod nvptx; +#[cfg(any(target_arch = "loongarch32", doc))] +#[doc(cfg(target_arch = "loongarch32"))] +mod loongarch32; + #[cfg(any(target_arch = "loongarch64", doc))] #[doc(cfg(target_arch = "loongarch64"))] mod loongarch64; diff --git a/crates/simd-test-macro/src/lib.rs b/crates/simd-test-macro/src/lib.rs index 18e4747d94..ae7849f298 100644 --- a/crates/simd-test-macro/src/lib.rs +++ b/crates/simd-test-macro/src/lib.rs @@ -62,7 +62,7 @@ pub fn simd_test( maybe_riscv if maybe_riscv.starts_with("riscv") => "is_riscv_feature_detected", "powerpc" | "powerpcle" => "is_powerpc_feature_detected", "powerpc64" | "powerpc64le" => "is_powerpc64_feature_detected", - "loongarch64" => "is_loongarch_feature_detected", + "loongarch32" | "loongarch64" => "is_loongarch_feature_detected", "s390x" => "is_s390x_feature_detected", t => panic!("unknown target: {t}"), }; diff --git a/crates/std_detect/README.md b/crates/std_detect/README.md index 091f5542e0..edc90d319a 100644 --- a/crates/std_detect/README.md +++ b/crates/std_detect/README.md @@ -55,7 +55,7 @@ crate from working on applications in which `std` is not available. application. * Linux/Android: - * `arm{32, 64}`, `mips{32,64}{,el}`, `powerpc{32,64}{,le}`, `loongarch64`, `s390x`: + * `arm{32, 64}`, `mips{32,64}{,el}`, `powerpc{32,64}{,le}`, `loongarch{32,64}`, `s390x`: `std_detect` supports these on Linux by querying ELF auxiliary vectors (using `getauxval` when available), and if that fails, by querying `/proc/self/auxv`. * `arm64`: partial support for doing run-time feature detection by directly diff --git a/crates/std_detect/src/detect/arch/loongarch.rs b/crates/std_detect/src/detect/arch/loongarch.rs index e9d68f6a9b..68fc600fa8 100644 --- a/crates/std_detect/src/detect/arch/loongarch.rs +++ b/crates/std_detect/src/detect/arch/loongarch.rs @@ -2,7 +2,7 @@ features! { @TARGET: loongarch; - @CFG: target_arch = "loongarch64"; + @CFG: any(target_arch = "loongarch32", target_arch = "loongarch64"); @MACRO_NAME: is_loongarch_feature_detected; @MACRO_ATTRS: /// Checks if `loongarch` feature is enabled. diff --git a/crates/std_detect/src/detect/arch/mod.rs b/crates/std_detect/src/detect/arch/mod.rs index d5a13acc02..b0be554ed8 100644 --- a/crates/std_detect/src/detect/arch/mod.rs +++ b/crates/std_detect/src/detect/arch/mod.rs @@ -49,7 +49,7 @@ cfg_if! { } else if #[cfg(target_arch = "mips64")] { #[unstable(feature = "stdarch_mips_feature_detection", issue = "111188")] pub use mips64::*; - } else if #[cfg(target_arch = "loongarch64")] { + } else if #[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] { #[stable(feature = "stdarch_loongarch_feature", since = "1.89.0")] pub use loongarch::*; } else if #[cfg(target_arch = "s390x")] { diff --git a/crates/std_detect/src/detect/mod.rs b/crates/std_detect/src/detect/mod.rs index 8fd3d95793..a9e9709c1f 100644 --- a/crates/std_detect/src/detect/mod.rs +++ b/crates/std_detect/src/detect/mod.rs @@ -103,6 +103,7 @@ pub fn features() -> impl Iterator { target_arch = "powerpc64", target_arch = "mips", target_arch = "mips64", + target_arch = "loongarch32", target_arch = "loongarch64", target_arch = "s390x", ))] { diff --git a/crates/std_detect/src/detect/os/linux/auxvec.rs b/crates/std_detect/src/detect/os/linux/auxvec.rs index c30379ff06..54f52aa753 100644 --- a/crates/std_detect/src/detect/os/linux/auxvec.rs +++ b/crates/std_detect/src/detect/os/linux/auxvec.rs @@ -80,6 +80,7 @@ pub(crate) fn auxv() -> Result { target_arch = "riscv64", target_arch = "mips", target_arch = "mips64", + target_arch = "loongarch32", target_arch = "loongarch64", ))] { @@ -182,6 +183,7 @@ fn auxv_from_buf(buf: &[usize]) -> Result { target_arch = "riscv64", target_arch = "mips", target_arch = "mips64", + target_arch = "loongarch32", target_arch = "loongarch64", ))] { diff --git a/crates/std_detect/src/detect/os/linux/mod.rs b/crates/std_detect/src/detect/os/linux/mod.rs index 8c689d0b1f..9accd41717 100644 --- a/crates/std_detect/src/detect/os/linux/mod.rs +++ b/crates/std_detect/src/detect/os/linux/mod.rs @@ -51,7 +51,7 @@ cfg_if::cfg_if! { } else if #[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))] { mod powerpc; pub(crate) use self::powerpc::detect_features; - } else if #[cfg(target_arch = "loongarch64")] { + } else if #[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] { mod loongarch; pub(crate) use self::loongarch::detect_features; } else if #[cfg(target_arch = "s390x")] { diff --git a/crates/std_detect/tests/macro_trailing_commas.rs b/crates/std_detect/tests/macro_trailing_commas.rs index fa3a23c796..2fee0abdd5 100644 --- a/crates/std_detect/tests/macro_trailing_commas.rs +++ b/crates/std_detect/tests/macro_trailing_commas.rs @@ -11,6 +11,7 @@ target_arch = "s390x", target_arch = "riscv32", target_arch = "riscv64", + target_arch = "loongarch32", target_arch = "loongarch64" ), feature(stdarch_internal) @@ -30,7 +31,7 @@ feature(stdarch_riscv_feature_detection) )] #![cfg_attr( - target_arch = "loongarch64", + any(target_arch = "loongarch32", target_arch = "loongarch64"), feature(stdarch_loongarch_feature_detection) )] @@ -45,6 +46,7 @@ target_arch = "s390x", target_arch = "riscv32", target_arch = "riscv64", + target_arch = "loongarch32", target_arch = "loongarch64" ))] #[macro_use] @@ -65,8 +67,8 @@ fn aarch64() { } #[test] -#[cfg(target_arch = "loongarch64")] -fn loongarch64() { +#[cfg(any(target_arch = "loongarch32", target_arch = "loongarch64"))] +fn loongarch() { let _ = is_loongarch_feature_detected!("lsx"); let _ = is_loongarch_feature_detected!("lsx",); }