Skip to content

Commit 0c6897b

Browse files
committed
RISC-V: Improvements of inline assembly uses
This commit performs various improvements (better register allocation, less register clobbering on the worst case and better readability) of RISC-V inline assembly use cases. Note that it does not change the `p` module (which defines the "P" extension draft instructions but very likely to change). 1. Use `lateout` as possible. Unlike `out(reg)` and `in(reg)`, `lateout(reg)` and `in(reg)` can share the same register, assuming that the register is written after all the reads are performed. It can improve the register allocation. 2. Add `preserves_flags` option as possible. While RISC-V doesn't have regular condition codes, RISC-V inline assembly in the Rust language assumes that some registers (mainly vector state registers) may be overwritten by default. By adding `preserves_flags` to the intrinsics corresponding instructions without overwriting such registers, it can minimize register clobbering on the worst case and adds flexibility to reorder the instructions. 3. Use trailing semicolon. As `asm!` declares an action and it doesn't return a value by itself, it would be better to have trailing semicolon to denote that an `asm!` call is effectively a statement.
1 parent 818f064 commit 0c6897b

File tree

2 files changed

+102
-51
lines changed

2 files changed

+102
-51
lines changed

crates/core_arch/src/riscv64/mod.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ pub use zk::*;
2020
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
2121
pub unsafe fn hlv_wu(src: *const u32) -> u32 {
2222
let value: u32;
23-
asm!(".insn i 0x73, 0x4, {}, {}, 0x681", out(reg) value, in(reg) src, options(readonly, nostack));
23+
asm!(
24+
".insn i 0x73, 0x4, {}, {}, 0x681",
25+
lateout(reg) value,
26+
in(reg) src,
27+
options(readonly, nostack, preserves_flags)
28+
);
2429
value
2530
}
2631

@@ -38,7 +43,12 @@ pub unsafe fn hlv_wu(src: *const u32) -> u32 {
3843
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
3944
pub unsafe fn hlv_d(src: *const i64) -> i64 {
4045
let value: i64;
41-
asm!(".insn i 0x73, 0x4, {}, {}, 0x6C0", out(reg) value, in(reg) src, options(readonly, nostack));
46+
asm!(
47+
".insn i 0x73, 0x4, {}, {}, 0x6C0",
48+
lateout(reg) value,
49+
in(reg) src,
50+
options(readonly, nostack, preserves_flags)
51+
);
4252
value
4353
}
4454

@@ -53,5 +63,5 @@ pub unsafe fn hlv_d(src: *const i64) -> i64 {
5363
#[inline]
5464
#[unstable(feature = "riscv_ext_intrinsics", issue = "114544")]
5565
pub unsafe fn hsv_d(dst: *mut i64, src: i64) {
56-
asm!(".insn r 0x73, 0x4, 0x37, x0, {}, {}", in(reg) dst, in(reg) src, options(nostack));
66+
asm!(".insn r 0x73, 0x4, 0x37, x0, {}, {}", in(reg) dst, in(reg) src, options(nostack, preserves_flags));
5767
}

0 commit comments

Comments
 (0)