Skip to content

Commit 643b06a

Browse files
committed
RISC-V: Use .insn on (Zkne or Zknd) intrinsics
Using the inline assembly and `.insn` could avoid current issues regarding intrinsics available when either Zknd or Zkne is available. Note that, coincidental success of the testing process depends on the possibly flaky disassembler behavior (which attempts to disassemble instructions *not* enabled on the target of the output object file) and should be removed now or if anything breaks.
1 parent a9a299d commit 643b06a

File tree

1 file changed

+20
-10
lines changed
  • crates/core_arch/src/riscv64

1 file changed

+20
-10
lines changed

crates/core_arch/src/riscv64/zk.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#[cfg(test)]
22
use stdarch_test::assert_instr;
33

4+
use crate::arch::asm;
5+
46
unsafe extern "unadjusted" {
57
#[link_name = "llvm.riscv.aes64es"]
68
fn _aes64es(rs1: i64, rs2: i64) -> i64;
@@ -14,12 +16,6 @@ unsafe extern "unadjusted" {
1416
#[link_name = "llvm.riscv.aes64dsm"]
1517
fn _aes64dsm(rs1: i64, rs2: i64) -> i64;
1618

17-
#[link_name = "llvm.riscv.aes64ks1i"]
18-
fn _aes64ks1i(rs1: i64, rnum: i32) -> i64;
19-
20-
#[link_name = "llvm.riscv.aes64ks2"]
21-
fn _aes64ks2(rs1: i64, rs2: i64) -> i64;
22-
2319
#[link_name = "llvm.riscv.aes64im"]
2420
fn _aes64im(rs1: i64) -> i64;
2521

@@ -135,13 +131,23 @@ pub fn aes64dsm(rs1: u64, rs2: u64) -> u64 {
135131
/// The `RNUM` parameter is expected to be a constant value inside the range of `0..=10`.
136132
//#[target_feature(enable = "zkne", enable = "zknd")] // TODO: zkne_or_zknd
137133
#[rustc_legacy_const_generics(1)]
138-
#[cfg_attr(test, assert_instr(aes64ks1i, RNUM = 0))]
134+
#[cfg_attr(test, assert_instr(aes64ks1i, RNUM = 0))] // REMOVE if anything goes wrong
139135
#[inline]
140136
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
141137
pub fn aes64ks1i<const RNUM: u8>(rs1: u64) -> u64 {
142138
static_assert!(RNUM <= 10);
143139

144-
unsafe { _aes64ks1i(rs1 as i64, RNUM as i32) as u64 }
140+
unsafe {
141+
let rd: u64;
142+
asm!(
143+
".insn i 0x13, 0x1, {}, {}, {}",
144+
lateout(reg) rd,
145+
in(reg) rs1,
146+
const 0x310 + (RNUM & 0x0f) as u16,
147+
options(pure, nomem, nostack)
148+
);
149+
rd
150+
}
145151
}
146152

147153
/// This instruction implements part of the KeySchedule operation for the AES Block cipher.
@@ -156,11 +162,15 @@ pub fn aes64ks1i<const RNUM: u8>(rs1: u64) -> u64 {
156162
///
157163
/// Section: 3.11
158164
//#[target_feature(enable = "zkne", enable = "zknd")] // TODO: zkne_or_zknd
159-
#[cfg_attr(test, assert_instr(aes64ks2))]
165+
#[cfg_attr(test, assert_instr(aes64ks2))] // REMOVE if anything goes wrong
160166
#[inline]
161167
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
162168
pub fn aes64ks2(rs1: u64, rs2: u64) -> u64 {
163-
unsafe { _aes64ks2(rs1 as i64, rs2 as i64) as u64 }
169+
unsafe {
170+
let rd: u64;
171+
asm!(".insn r 0x33, 0x0, 0x3f, {}, {}, {}", lateout(reg) rd, in(reg) rs1, in(reg) rs2, options(pure, nomem, nostack));
172+
rd
173+
}
164174
}
165175

166176
/// This instruction accelerates the inverse MixColumns step of the AES Block Cipher, and is used to aid creation of

0 commit comments

Comments
 (0)