Skip to content

Commit 1550c48

Browse files
committed
Impl: Add RISC-V Zb intrinsics
1 parent f17c175 commit 1550c48

File tree

2 files changed

+152
-0
lines changed

2 files changed

+152
-0
lines changed

crates/core_arch/src/riscv_shared/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
//! Shared RISC-V intrinsics
22
33
mod p;
4+
mod zb;
45
mod zk;
56

67
#[unstable(feature = "stdsimd", issue = "27731")]
78
pub use p::*;
9+
pub use zb::*;
810
pub use zk::*;
911

1012
use crate::arch::asm;
+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#[cfg(test)]
2+
use stdarch_test::assert_instr;
3+
4+
#[cfg(target_arch = "riscv32")]
5+
extern "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")]
20+
extern "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+
#[target_feature(enable = "zbb")]
50+
// See #1464
51+
// #[cfg_attr(test, assert_instr(orc.b))]
52+
#[inline]
53+
pub 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+
#[target_feature(enable = "zbc")]
79+
// See #1464
80+
// #[cfg_attr(test, assert_instr(clmul))]
81+
#[inline]
82+
pub 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+
#[target_feature(enable = "zbc")]
108+
// See #1464
109+
// #[cfg_attr(test, assert_instr(clmulh))]
110+
#[inline]
111+
pub 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+
#[target_feature(enable = "zbc")]
137+
// See #1464
138+
// #[cfg_attr(test, assert_instr(clmulr))]
139+
#[inline]
140+
pub 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+
}

0 commit comments

Comments
 (0)