core/stdarch/crates/core_arch/src/riscv_shared/
zb.rs

1#[cfg(test)]
2use stdarch_test::assert_instr;
3
4#[cfg(target_arch = "riscv32")]
5extern "unadjusted" {
6    #[link_name = "llvm.riscv.orc.b.i32"]
7    fn _orc_b_32(rs: i32) -> i32;
8
9    #[link_name = "llvm.riscv.clmul.i32"]
10    fn _clmul_32(rs1: i32, rs2: i32) -> i32;
11
12    #[link_name = "llvm.riscv.clmulh.i32"]
13    fn _clmulh_32(rs1: i32, rs2: i32) -> i32;
14
15    #[link_name = "llvm.riscv.clmulr.i32"]
16    fn _clmulr_32(rs1: i32, rs2: i32) -> i32;
17}
18
19#[cfg(target_arch = "riscv64")]
20extern "unadjusted" {
21    #[link_name = "llvm.riscv.orc.b.i64"]
22    fn _orc_b_64(rs1: i64) -> i64;
23
24    #[link_name = "llvm.riscv.clmul.i64"]
25    fn _clmul_64(rs1: i64, rs2: i64) -> i64;
26
27    #[link_name = "llvm.riscv.clmulh.i64"]
28    fn _clmulh_64(rs1: i64, rs2: i64) -> i64;
29
30    #[link_name = "llvm.riscv.clmulr.i64"]
31    fn _clmulr_64(rs1: i64, rs2: i64) -> i64;
32}
33
34/// Bitwise OR-Combine, byte granule
35///
36/// Combines the bits within every byte through a reciprocal bitwise logical OR. This sets the bits of each byte in
37/// 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
38/// respective byte of rs is set.
39///
40/// Source: RISC-V Bit-Manipulation ISA-extensions
41///
42/// Version: v1.0.0
43///
44/// Section: 2.24
45///
46/// # Safety
47///
48/// This function is safe to use if the `zbb` target feature is present.
49#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
50#[target_feature(enable = "zbb")]
51#[cfg_attr(test, assert_instr(orc.b))]
52#[inline]
53pub unsafe fn orc_b(rs: usize) -> usize {
54    #[cfg(target_arch = "riscv32")]
55    {
56        _orc_b_32(rs as i32) as usize
57    }
58
59    #[cfg(target_arch = "riscv64")]
60    {
61        _orc_b_64(rs as i64) as usize
62    }
63}
64
65/// Carry-less multiply (low-part)
66///
67/// clmul produces the lower half of the 2·XLEN carry-less product.
68///
69/// Source: RISC-V Bit-Manipulation ISA-extensions
70///
71/// Version: v1.0.0
72///
73/// Section: 2.11
74///
75/// # Safety
76///
77/// This function is safe to use if the `zbc` target feature is present.
78#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
79#[target_feature(enable = "zbc")]
80#[cfg_attr(test, assert_instr(clmul))]
81#[inline]
82pub unsafe fn clmul(rs1: usize, rs2: usize) -> usize {
83    #[cfg(target_arch = "riscv32")]
84    {
85        _clmul_32(rs1 as i32, rs2 as i32) as usize
86    }
87
88    #[cfg(target_arch = "riscv64")]
89    {
90        _clmul_64(rs1 as i64, rs2 as i64) as usize
91    }
92}
93
94/// Carry-less multiply (high-part)
95///
96/// clmulh produces the upper half of the 2·XLEN carry-less product.
97///
98/// Source: RISC-V Bit-Manipulation ISA-extensions
99///
100/// Version: v1.0.0
101///
102/// Section: 2.12
103///
104/// # Safety
105///
106/// This function is safe to use if the `zbc` target feature is present.
107#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
108#[target_feature(enable = "zbc")]
109#[cfg_attr(test, assert_instr(clmulh))]
110#[inline]
111pub unsafe fn clmulh(rs1: usize, rs2: usize) -> usize {
112    #[cfg(target_arch = "riscv32")]
113    {
114        _clmulh_32(rs1 as i32, rs2 as i32) as usize
115    }
116
117    #[cfg(target_arch = "riscv64")]
118    {
119        _clmulh_64(rs1 as i64, rs2 as i64) as usize
120    }
121}
122
123/// Carry-less multiply (reversed)
124///
125/// clmulr produces bits 2·XLEN−2:XLEN-1 of the 2·XLEN carry-less product.
126///
127/// Source: RISC-V Bit-Manipulation ISA-extensions
128///
129/// Version: v1.0.0
130///
131/// Section: 2.13
132///
133/// # Safety
134///
135/// This function is safe to use if the `zbc` target feature is present.
136#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
137#[target_feature(enable = "zbc")]
138#[cfg_attr(test, assert_instr(clmulr))]
139#[inline]
140pub unsafe fn clmulr(rs1: usize, rs2: usize) -> usize {
141    #[cfg(target_arch = "riscv32")]
142    {
143        _clmulr_32(rs1 as i32, rs2 as i32) as usize
144    }
145
146    #[cfg(target_arch = "riscv64")]
147    {
148        _clmulr_64(rs1 as i64, rs2 as i64) as usize
149    }
150}