about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGijs Burghoorn <me@gburghoorn.com>2023-09-01 17:18:17 +0200
committerAmanieu d'Antras <amanieu@gmail.com>2023-09-01 18:32:40 +0200
commitc460cf67060242f34153a247eaf9ad047d4eb30f (patch)
tree1aed0119bab53a2d239f6898ef5515c2bb752e1f
parentd1229d008b3ed0c19f0433ba1b20cf0a3f64c4ef (diff)
downloadrust-c460cf67060242f34153a247eaf9ad047d4eb30f.tar.gz
rust-c460cf67060242f34153a247eaf9ad047d4eb30f.zip
Impl: Add RISC-V Zb intrinsics
-rw-r--r--library/stdarch/crates/core_arch/src/riscv_shared/mod.rs2
-rw-r--r--library/stdarch/crates/core_arch/src/riscv_shared/zb.rs150
2 files changed, 152 insertions, 0 deletions
diff --git a/library/stdarch/crates/core_arch/src/riscv_shared/mod.rs b/library/stdarch/crates/core_arch/src/riscv_shared/mod.rs
index d14431ead49..14f6989d20a 100644
--- a/library/stdarch/crates/core_arch/src/riscv_shared/mod.rs
+++ b/library/stdarch/crates/core_arch/src/riscv_shared/mod.rs
@@ -1,10 +1,12 @@
 //! Shared RISC-V intrinsics
 
 mod p;
+mod zb;
 mod zk;
 
 #[unstable(feature = "stdsimd", issue = "27731")]
 pub use p::*;
+pub use zb::*;
 pub use zk::*;
 
 use crate::arch::asm;
diff --git a/library/stdarch/crates/core_arch/src/riscv_shared/zb.rs b/library/stdarch/crates/core_arch/src/riscv_shared/zb.rs
new file mode 100644
index 00000000000..cfae6caa530
--- /dev/null
+++ b/library/stdarch/crates/core_arch/src/riscv_shared/zb.rs
@@ -0,0 +1,150 @@
+#[cfg(test)]
+use stdarch_test::assert_instr;
+
+#[cfg(target_arch = "riscv32")]
+extern "unadjusted" {
+    #[link_name = "llvm.riscv.orc.b.i32"]
+    fn _orc_b_32(rs: i32) -> i32;
+
+    #[link_name = "llvm.riscv.clmul.i32"]
+    fn _clmul_32(rs1: i32, rs2: i32) -> i32;
+
+    #[link_name = "llvm.riscv.clmulh.i32"]
+    fn _clmulh_32(rs1: i32, rs2: i32) -> i32;
+
+    #[link_name = "llvm.riscv.clmulr.i32"]
+    fn _clmulr_32(rs1: i32, rs2: i32) -> i32;
+}
+
+#[cfg(target_arch = "riscv64")]
+extern "unadjusted" {
+    #[link_name = "llvm.riscv.orc.b.i64"]
+    fn _orc_b_64(rs1: i64) -> i64;
+
+    #[link_name = "llvm.riscv.clmul.i64"]
+    fn _clmul_64(rs1: i64, rs2: i64) -> i64;
+
+    #[link_name = "llvm.riscv.clmulh.i64"]
+    fn _clmulh_64(rs1: i64, rs2: i64) -> i64;
+
+    #[link_name = "llvm.riscv.clmulr.i64"]
+    fn _clmulr_64(rs1: i64, rs2: i64) -> i64;
+}
+
+/// Bitwise OR-Combine, byte granule
+///
+/// Combines the bits within every byte through a reciprocal bitwise logical OR. This sets the bits of each byte in
+/// the result rd to all zeros if no bit within the respective byte of rs is set, or to all ones if any bit within the
+/// respective byte of rs is set.
+///
+/// Source: RISC-V Bit-Manipulation ISA-extensions
+///
+/// Version: v1.0.0
+///
+/// Section: 2.24
+///
+/// # Safety
+///
+/// This function is safe to use if the `zbb` target feature is present.
+#[target_feature(enable = "zbb")]
+// See #1464
+// #[cfg_attr(test, assert_instr(orc.b))]
+#[inline]
+pub unsafe fn orc_b(rs: usize) -> usize {
+    #[cfg(target_arch = "riscv32")]
+    {
+        _orc_b_32(rs as i32) as usize
+    }
+
+    #[cfg(target_arch = "riscv64")]
+    {
+        _orc_b_64(rs as i64) as usize
+    }
+}
+
+/// Carry-less multiply (low-part)
+///
+/// clmul produces the lower half of the 2·XLEN carry-less product.
+///
+/// Source: RISC-V Bit-Manipulation ISA-extensions
+///
+/// Version: v1.0.0
+///
+/// Section: 2.11
+///
+/// # Safety
+///
+/// This function is safe to use if the `zbc` target feature is present.
+#[target_feature(enable = "zbc")]
+// See #1464
+// #[cfg_attr(test, assert_instr(clmul))]
+#[inline]
+pub unsafe fn clmul(rs1: usize, rs2: usize) -> usize {
+    #[cfg(target_arch = "riscv32")]
+    {
+        _clmul_32(rs1 as i32, rs2 as i32) as usize
+    }
+
+    #[cfg(target_arch = "riscv64")]
+    {
+        _clmul_64(rs1 as i64, rs2 as i64) as usize
+    }
+}
+
+/// Carry-less multiply (high-part)
+///
+/// clmulh produces the upper half of the 2·XLEN carry-less product.
+///
+/// Source: RISC-V Bit-Manipulation ISA-extensions
+///
+/// Version: v1.0.0
+///
+/// Section: 2.12
+///
+/// # Safety
+///
+/// This function is safe to use if the `zbc` target feature is present.
+#[target_feature(enable = "zbc")]
+// See #1464
+// #[cfg_attr(test, assert_instr(clmulh))]
+#[inline]
+pub unsafe fn clmulh(rs1: usize, rs2: usize) -> usize {
+    #[cfg(target_arch = "riscv32")]
+    {
+        _clmulh_32(rs1 as i32, rs2 as i32) as usize
+    }
+
+    #[cfg(target_arch = "riscv64")]
+    {
+        _clmulh_64(rs1 as i64, rs2 as i64) as usize
+    }
+}
+
+/// Carry-less multiply (reversed)
+///
+/// clmulr produces bits 2·XLEN−2:XLEN-1 of the 2·XLEN carry-less product.
+///
+/// Source: RISC-V Bit-Manipulation ISA-extensions
+///
+/// Version: v1.0.0
+///
+/// Section: 2.13
+///
+/// # Safety
+///
+/// This function is safe to use if the `zbc` target feature is present.
+#[target_feature(enable = "zbc")]
+// See #1464
+// #[cfg_attr(test, assert_instr(clmulr))]
+#[inline]
+pub unsafe fn clmulr(rs1: usize, rs2: usize) -> usize {
+    #[cfg(target_arch = "riscv32")]
+    {
+        _clmulr_32(rs1 as i32, rs2 as i32) as usize
+    }
+
+    #[cfg(target_arch = "riscv64")]
+    {
+        _clmulr_64(rs1 as i64, rs2 as i64) as usize
+    }
+}