Skip to content

Commit 8df078a

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)` pair, `lateout(reg)` and `in(reg)` can share the same register because they state that the late-output register is written after all the reads are performed. It can improve 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 them, it can minimize register clobbering on the worst case. 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. 4. Make most of `asm!` calls multi-lined. `rustfmt` makes some simple (yet long) `asm!` calls multi-lined but it does not perform formatting of complex `asm!` calls with inputs and/or outputs. To keep consistency, it makes most of the `asm!` calls multi-lined.
1 parent 3338743 commit 8df078a

File tree

2 files changed

+215
-51
lines changed
  • library/stdarch/crates/core_arch/src

2 files changed

+215
-51
lines changed

library/stdarch/crates/core_arch/src/riscv64/mod.rs

Lines changed: 18 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,10 @@ 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!(
67+
".insn r 0x73, 0x4, 0x37, x0, {}, {}",
68+
in(reg) dst,
69+
in(reg) src,
70+
options(nostack, preserves_flags)
71+
);
5772
}

0 commit comments

Comments
 (0)