Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crates/core_arch/src/riscv32/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
//! RISC-V RV32 specific intrinsics

mod zb;
mod zk;

#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub use zb::*;

#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub use zk::*;
137 changes: 137 additions & 0 deletions crates/core_arch/src/riscv32/zb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#[cfg(test)]
use stdarch_test::assert_instr;

unsafe extern "llvm-intrinsic" {
#[link_name = "llvm.riscv.xperm8.i32"]
fn _xperm8_32(rs1: u32, rs2: u32) -> u32;

#[link_name = "llvm.riscv.xperm4.i32"]
fn _xperm4_32(rs1: u32, rs2: u32) -> u32;

#[link_name = "llvm.riscv.clmulh.i32"]
fn _clmulh_32(rs1: u32, rs2: u32) -> u32;

#[link_name = "llvm.riscv.clmulr.i32"]
fn _clmulr_32(rs1: u32, rs2: u32) -> u32;

#[link_name = "llvm.riscv.zip.i32"]
fn _zip_32(rs1: u32) -> u32;

#[link_name = "llvm.riscv.unzip.i32"]
fn _unzip_32(rs1: u32) -> u32;
}

/// Byte-wise lookup of indices into a vector in registers.
///
/// The xperm8 instruction operates on bytes. The rs1 register contains a vector of 4
/// 8-bit elements. The rs2 register contains a vector of 4 8-bit indexes. The result is
/// each element in rs2 replaced by the indexed element in rs1, or zero if the index into rs2
/// is out of bounds.
///
/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
///
/// Version: v1.0.1
///
/// Section: 3.47
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
#[target_feature(enable = "zbkx")]
#[cfg_attr(test, assert_instr(xperm8))]
#[inline]
pub fn xperm8_32(rs1: u32, rs2: u32) -> u32 {
unsafe { _xperm8_32(rs1, rs2) }
}
Comment thread
TechnoPorg marked this conversation as resolved.

/// Nibble-wise lookup of indices into a vector.
///
/// The xperm4 instruction operates on nibbles. The rs1 register contains a vector of 8
/// 4-bit elements. The rs2 register contains a vector of 8 4-bit indexes. The result is
/// each element in rs2 replaced by the indexed element in rs1, or zero if the index into rs2
/// is out of bounds.
///
/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
///
/// Version: v1.0.1
///
/// Section: 3.48
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
#[target_feature(enable = "zbkx")]
#[cfg_attr(test, assert_instr(xperm4))]
#[inline]
pub fn xperm4_32(rs1: u32, rs2: u32) -> u32 {
unsafe { _xperm4_32(rs1, rs2) }
}

/// Carry-less multiply (high-part)
///
/// clmulh produces the upper half of the 64-bit carry-less product.
///
/// Source: RISC-V Bit-Manipulation ISA-extensions
///
/// Version: v1.0.0
///
/// Section: 2.12
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
#[target_feature(enable = "zbkc")]
#[cfg_attr(test, assert_instr(clmulh))]
#[inline]
pub fn clmulh_32(rs1: u32, rs2: u32) -> u32 {
unsafe { _clmulh_32(rs1, rs2) }
}

/// Carry-less multiply (reversed)
///
/// clmulr produces bits 62:31 of the 64-bit carry-less product.
///
/// Source: RISC-V Bit-Manipulation ISA-extensions
///
/// Version: v1.0.0
///
/// Section: 2.13
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
#[target_feature(enable = "zbc")]
#[cfg_attr(test, assert_instr(clmulr))]
#[inline]
pub fn clmulr_32(rs1: u32, rs2: u32) -> u32 {
unsafe { _clmulr_32(rs1, rs2) }
}

/// Place upper/lower halves of the source register into odd/even bits of the destination
/// respectivley.
///
/// This instruction places bits in the low half of the source register into the even bit
/// positions of the destination, and bits in the high half of the source register into the odd
/// bit positions of the destination. It is the inverse of the unzip instruction. This
/// instruction is available only on RV32.
///
/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
///
/// Version: v1.0.1
///
/// Section: 3.49
#[target_feature(enable = "zbkb")]
// See #1464
// #[cfg_attr(test, assert_instr(zip))]
#[inline]
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub fn zip_32(rs: u32) -> u32 {
unsafe { _zip_32(rs) }
}

/// Place odd and even bits of the source word into upper/lower halves of the destination.
///
/// This instruction places the even bits of the source register into the low half of the
/// destination, and the odd bits of the source into the high bits of the destination. It is
/// the inverse of the zip instruction. This instruction is available only on RV32.
///
/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
///
/// Version: v1.0.1
///
/// Section: 3.45
#[target_feature(enable = "zbkb")]
#[cfg_attr(test, assert_instr(unzip))]
#[inline]
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub fn unzip_32(rs: u32) -> u32 {
unsafe { _unzip_32(rs) }
}
89 changes: 21 additions & 68 deletions crates/core_arch/src/riscv32/zk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,40 +3,34 @@ use stdarch_test::assert_instr;

unsafe extern "llvm-intrinsic" {
#[link_name = "llvm.riscv.aes32esi"]
fn _aes32esi(rs1: i32, rs2: i32, bs: i32) -> i32;
fn _aes32esi(rs1: u32, rs2: u32, bs: u32) -> u32;

#[link_name = "llvm.riscv.aes32esmi"]
fn _aes32esmi(rs1: i32, rs2: i32, bs: i32) -> i32;
fn _aes32esmi(rs1: u32, rs2: u32, bs: u32) -> u32;

#[link_name = "llvm.riscv.aes32dsi"]
fn _aes32dsi(rs1: i32, rs2: i32, bs: i32) -> i32;
fn _aes32dsi(rs1: u32, rs2: u32, bs: u32) -> u32;

#[link_name = "llvm.riscv.aes32dsmi"]
fn _aes32dsmi(rs1: i32, rs2: i32, bs: i32) -> i32;

#[link_name = "llvm.riscv.zip.i32"]
fn _zip(rs1: i32) -> i32;

#[link_name = "llvm.riscv.unzip.i32"]
fn _unzip(rs1: i32) -> i32;
fn _aes32dsmi(rs1: u32, rs2: u32, bs: u32) -> u32;

#[link_name = "llvm.riscv.sha512sig0h"]
fn _sha512sig0h(rs1: i32, rs2: i32) -> i32;
fn _sha512sig0h(rs1: u32, rs2: u32) -> u32;

#[link_name = "llvm.riscv.sha512sig0l"]
fn _sha512sig0l(rs1: i32, rs2: i32) -> i32;
fn _sha512sig0l(rs1: u32, rs2: u32) -> u32;

#[link_name = "llvm.riscv.sha512sig1h"]
fn _sha512sig1h(rs1: i32, rs2: i32) -> i32;
fn _sha512sig1h(rs1: u32, rs2: u32) -> u32;

#[link_name = "llvm.riscv.sha512sig1l"]
fn _sha512sig1l(rs1: i32, rs2: i32) -> i32;
fn _sha512sig1l(rs1: u32, rs2: u32) -> u32;

#[link_name = "llvm.riscv.sha512sum0r"]
fn _sha512sum0r(rs1: i32, rs2: i32) -> i32;
fn _sha512sum0r(rs1: u32, rs2: u32) -> u32;

#[link_name = "llvm.riscv.sha512sum1r"]
fn _sha512sum1r(rs1: i32, rs2: i32) -> i32;
fn _sha512sum1r(rs1: u32, rs2: u32) -> u32;
}

/// AES final round encryption instruction for RV32.
Expand Down Expand Up @@ -65,10 +59,10 @@ unsafe extern "llvm-intrinsic" {
pub fn aes32esi<const BS: u8>(rs1: u32, rs2: u32) -> u32 {
static_assert!(BS < 4);

unsafe { _aes32esi(rs1 as i32, rs2 as i32, BS as i32) as u32 }
unsafe { _aes32esi(rs1, rs2, BS as u32) }
}

/// AES middle round encryption instruction for RV32 with.
/// AES middle round encryption instruction for RV32.
///
/// This instruction sources a single byte from rs2 according to bs. To this it applies the
/// forward AES SBox operation, and a partial forward MixColumn, before XOR’ing the result with
Expand All @@ -94,7 +88,7 @@ pub fn aes32esi<const BS: u8>(rs1: u32, rs2: u32) -> u32 {
pub fn aes32esmi<const BS: u8>(rs1: u32, rs2: u32) -> u32 {
static_assert!(BS < 4);

unsafe { _aes32esmi(rs1 as i32, rs2 as i32, BS as i32) as u32 }
unsafe { _aes32esmi(rs1, rs2, BS as u32) }
}

/// AES final round decryption instruction for RV32.
Expand Down Expand Up @@ -122,7 +116,7 @@ pub fn aes32esmi<const BS: u8>(rs1: u32, rs2: u32) -> u32 {
pub fn aes32dsi<const BS: u8>(rs1: u32, rs2: u32) -> u32 {
static_assert!(BS < 4);

unsafe { _aes32dsi(rs1 as i32, rs2 as i32, BS as i32) as u32 }
unsafe { _aes32dsi(rs1, rs2, BS as u32) }
}

/// AES middle round decryption instruction for RV32.
Expand Down Expand Up @@ -151,48 +145,7 @@ pub fn aes32dsi<const BS: u8>(rs1: u32, rs2: u32) -> u32 {
pub fn aes32dsmi<const BS: u8>(rs1: u32, rs2: u32) -> u32 {
static_assert!(BS < 4);

unsafe { _aes32dsmi(rs1 as i32, rs2 as i32, BS as i32) as u32 }
}

/// Place upper/lower halves of the source register into odd/even bits of the destination
/// respectivley.
///
/// This instruction places bits in the low half of the source register into the even bit
/// positions of the destination, and bits in the high half of the source register into the odd
/// bit positions of the destination. It is the inverse of the unzip instruction. This
/// instruction is available only on RV32.
///
/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
///
/// Version: v1.0.1
///
/// Section: 3.49
#[target_feature(enable = "zbkb")]
// See #1464
// #[cfg_attr(test, assert_instr(zip))]
#[inline]
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub fn zip(rs: u32) -> u32 {
unsafe { _zip(rs as i32) as u32 }
}

/// Place odd and even bits of the source word into upper/lower halves of the destination.
///
/// This instruction places the even bits of the source register into the low half of the
/// destination, and the odd bits of the source into the high bits of the destination. It is
/// the inverse of the zip instruction. This instruction is available only on RV32.
///
/// Source: RISC-V Cryptography Extensions Volume I: Scalar & Entropy Source Instructions
///
/// Version: v1.0.1
///
/// Section: 3.45
#[target_feature(enable = "zbkb")]
#[cfg_attr(test, assert_instr(unzip))]
#[inline]
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub fn unzip(rs: u32) -> u32 {
unsafe { _unzip(rs as i32) as u32 }
unsafe { _aes32dsmi(rs1, rs2, BS as u32) }
}

/// Implements the high half of the Sigma0 transformation, as used in the SHA2-512 hash
Expand All @@ -215,7 +168,7 @@ pub fn unzip(rs: u32) -> u32 {
#[inline]
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub fn sha512sig0h(rs1: u32, rs2: u32) -> u32 {
unsafe { _sha512sig0h(rs1 as i32, rs2 as i32) as u32 }
unsafe { _sha512sig0h(rs1, rs2) }
}

/// Implements the low half of the Sigma0 transformation, as used in the SHA2-512 hash function
Expand All @@ -238,7 +191,7 @@ pub fn sha512sig0h(rs1: u32, rs2: u32) -> u32 {
#[inline]
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub fn sha512sig0l(rs1: u32, rs2: u32) -> u32 {
unsafe { _sha512sig0l(rs1 as i32, rs2 as i32) as u32 }
unsafe { _sha512sig0l(rs1, rs2) }
}

/// Implements the high half of the Sigma1 transformation, as used in the SHA2-512 hash
Expand All @@ -261,7 +214,7 @@ pub fn sha512sig0l(rs1: u32, rs2: u32) -> u32 {
#[inline]
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub fn sha512sig1h(rs1: u32, rs2: u32) -> u32 {
unsafe { _sha512sig1h(rs1 as i32, rs2 as i32) as u32 }
unsafe { _sha512sig1h(rs1, rs2) }
}

/// Implements the low half of the Sigma1 transformation, as used in the SHA2-512 hash function
Expand All @@ -283,7 +236,7 @@ pub fn sha512sig1h(rs1: u32, rs2: u32) -> u32 {
#[inline]
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub fn sha512sig1l(rs1: u32, rs2: u32) -> u32 {
unsafe { _sha512sig1l(rs1 as i32, rs2 as i32) as u32 }
unsafe { _sha512sig1l(rs1, rs2) }
}

/// Implements the Sum0 transformation, as used in the SHA2-512 hash function \[49\] (Section
Expand All @@ -305,7 +258,7 @@ pub fn sha512sig1l(rs1: u32, rs2: u32) -> u32 {
#[inline]
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub fn sha512sum0r(rs1: u32, rs2: u32) -> u32 {
unsafe { _sha512sum0r(rs1 as i32, rs2 as i32) as u32 }
unsafe { _sha512sum0r(rs1, rs2) }
}

/// Implements the Sum1 transformation, as used in the SHA2-512 hash function \[49\] (Section
Expand All @@ -327,5 +280,5 @@ pub fn sha512sum0r(rs1: u32, rs2: u32) -> u32 {
#[inline]
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub fn sha512sum1r(rs1: u32, rs2: u32) -> u32 {
unsafe { _sha512sum1r(rs1 as i32, rs2 as i32) as u32 }
unsafe { _sha512sum1r(rs1, rs2) }
}
4 changes: 4 additions & 0 deletions crates/core_arch/src/riscv64/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
//! RISC-V RV64 specific intrinsics
use crate::arch::asm;

mod zb;
mod zk;

#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub use zb::*;

#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
pub use zk::*;

Expand Down
Loading
Loading