From b5ed5987720e7e75ac088a9970780ff9373482e5 Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Thu, 11 Sep 2025 06:07:02 +0000 Subject: [PATCH 1/2] RISC-V: Change `target_feature` on (Zkne or Zknd) instrinsics **DRAFT: THIS COMMIT SHALL BE SQUASHED INTO THE NEXT COMMIT.** Because changes to rustc are not performed yet, we cannot switch `#[target_feature]` attribute to enable desired features. Instead, this commit just comments out `#[target_feature]`. --- crates/core_arch/src/riscv64/zk.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/core_arch/src/riscv64/zk.rs b/crates/core_arch/src/riscv64/zk.rs index a30653cbe0..8b26243aaf 100644 --- a/crates/core_arch/src/riscv64/zk.rs +++ b/crates/core_arch/src/riscv64/zk.rs @@ -133,7 +133,7 @@ pub fn aes64dsm(rs1: u64, rs2: u64) -> u64 { /// # Note /// /// The `RNUM` parameter is expected to be a constant value inside the range of `0..=10`. -#[target_feature(enable = "zkne", enable = "zknd")] +//#[target_feature(enable = "zkne", enable = "zknd")] // TODO: zkne_or_zknd #[rustc_legacy_const_generics(1)] #[cfg_attr(test, assert_instr(aes64ks1i, RNUM = 0))] #[inline] @@ -155,7 +155,7 @@ pub fn aes64ks1i(rs1: u64) -> u64 { /// Version: v1.0.1 /// /// Section: 3.11 -#[target_feature(enable = "zkne", enable = "zknd")] +//#[target_feature(enable = "zkne", enable = "zknd")] // TODO: zkne_or_zknd #[cfg_attr(test, assert_instr(aes64ks2))] #[inline] #[unstable(feature = "riscv_ext_intrinsics", issue = "114544")] From 1a47fad72bc5383bb7c90bef02a0a7815a966350 Mon Sep 17 00:00:00 2001 From: Tsukasa OI Date: Thu, 11 Sep 2025 05:36:06 +0000 Subject: [PATCH 2/2] 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. --- crates/core_arch/src/riscv64/zk.rs | 36 +++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/crates/core_arch/src/riscv64/zk.rs b/crates/core_arch/src/riscv64/zk.rs index 8b26243aaf..b39a384b34 100644 --- a/crates/core_arch/src/riscv64/zk.rs +++ b/crates/core_arch/src/riscv64/zk.rs @@ -1,6 +1,8 @@ #[cfg(test)] use stdarch_test::assert_instr; +use crate::arch::asm; + unsafe extern "unadjusted" { #[link_name = "llvm.riscv.aes64es"] fn _aes64es(rs1: i64, rs2: i64) -> i64; @@ -14,12 +16,6 @@ unsafe extern "unadjusted" { #[link_name = "llvm.riscv.aes64dsm"] fn _aes64dsm(rs1: i64, rs2: i64) -> i64; - #[link_name = "llvm.riscv.aes64ks1i"] - fn _aes64ks1i(rs1: i64, rnum: i32) -> i64; - - #[link_name = "llvm.riscv.aes64ks2"] - fn _aes64ks2(rs1: i64, rs2: i64) -> i64; - #[link_name = "llvm.riscv.aes64im"] fn _aes64im(rs1: i64) -> i64; @@ -135,13 +131,23 @@ pub fn aes64dsm(rs1: u64, rs2: u64) -> u64 { /// The `RNUM` parameter is expected to be a constant value inside the range of `0..=10`. //#[target_feature(enable = "zkne", enable = "zknd")] // TODO: zkne_or_zknd #[rustc_legacy_const_generics(1)] -#[cfg_attr(test, assert_instr(aes64ks1i, RNUM = 0))] +#[cfg_attr(test, assert_instr(aes64ks1i, RNUM = 0))] // REMOVE if anything goes wrong #[inline] #[unstable(feature = "riscv_ext_intrinsics", issue = "114544")] pub fn aes64ks1i(rs1: u64) -> u64 { static_assert!(RNUM <= 10); - unsafe { _aes64ks1i(rs1 as i64, RNUM as i32) as u64 } + unsafe { + let rd: u64; + asm!( + ".insn i 0x13, 0x1, {}, {}, {}", + lateout(reg) rd, + in(reg) rs1, + const 0x310 + (RNUM & 0x0f) as u16, + options(pure, nomem, nostack, preserves_flags) + ); + rd + } } /// This instruction implements part of the KeySchedule operation for the AES Block cipher. @@ -156,11 +162,21 @@ pub fn aes64ks1i(rs1: u64) -> u64 { /// /// Section: 3.11 //#[target_feature(enable = "zkne", enable = "zknd")] // TODO: zkne_or_zknd -#[cfg_attr(test, assert_instr(aes64ks2))] +#[cfg_attr(test, assert_instr(aes64ks2))] // REMOVE if anything goes wrong #[inline] #[unstable(feature = "riscv_ext_intrinsics", issue = "114544")] pub fn aes64ks2(rs1: u64, rs2: u64) -> u64 { - unsafe { _aes64ks2(rs1 as i64, rs2 as i64) as u64 } + unsafe { + let rd: u64; + asm!( + ".insn r 0x33, 0x0, 0x3f, {}, {}, {}", + lateout(reg) rd, + in(reg) rs1, + in(reg) rs2, + options(pure, nomem, nostack, preserves_flags) + ); + rd + } } /// This instruction accelerates the inverse MixColumns step of the AES Block Cipher, and is used to aid creation of