| #[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")] |
| #[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")] |
| #[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")] |
| #[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")] |
| #[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 |
| } |
| } |