Skip to content

Commit 2a84e9a

Browse files
committed
riscv: hypervisor load and store instructions
adds `riscv64` module
1 parent 5422ffd commit 2a84e9a

File tree

3 files changed

+234
-0
lines changed

3 files changed

+234
-0
lines changed

crates/core_arch/src/mod.rs

+15
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,17 @@ pub mod arch {
6666
pub use crate::core_arch::riscv::*;
6767
}
6868

69+
/// Platform-specific intrinsics for the `riscv64` platform.
70+
///
71+
/// See the [module documentation](../index.html) for more details.
72+
#[cfg(any(target_arch = "riscv64", doc))]
73+
#[doc(cfg(any(target_arch = "riscv64")))]
74+
#[unstable(feature = "stdsimd", issue = "27731")]
75+
pub mod riscv64 {
76+
pub use crate::core_arch::riscv::*;
77+
pub use crate::core_arch::riscv64::*;
78+
}
79+
6980
/// Platform-specific intrinsics for the `wasm32` platform.
7081
///
7182
/// This module provides intrinsics specific to the WebAssembly
@@ -266,6 +277,10 @@ mod arm;
266277
#[doc(cfg(any(target_arch = "riscv32", target_arch = "riscv64")))]
267278
mod riscv;
268279

280+
#[cfg(any(target_arch = "riscv64", doc))]
281+
#[doc(cfg(any(target_arch = "riscv64")))]
282+
mod riscv64;
283+
269284
#[cfg(any(target_family = "wasm", doc))]
270285
#[doc(cfg(target_family = "wasm"))]
271286
mod wasm32;

crates/core_arch/src/riscv/mod.rs

+164
Original file line numberDiff line numberDiff line change
@@ -143,3 +143,167 @@ pub unsafe fn sfence_w_inval() {
143143
pub unsafe fn sfence_inval_ir() {
144144
asm!(".insn i 0x73, 0, x0, x0, 0x181")
145145
}
146+
147+
/// Loads memory from hypervisor by signed byte integer
148+
///
149+
/// This instruction performs an explicit memory access as though `V=1`;
150+
/// i.e., with the address translation and protection, and the endianness, that apply to memory
151+
/// accesses in either VS-mode or VU-mode.
152+
///
153+
/// # Unsafety
154+
///
155+
/// This function accesses the virtual supervisor or user via a `HLV.B` instruction which is effectively
156+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
157+
#[inline]
158+
pub unsafe fn hlv_b(src: *const i8) -> i8 {
159+
let value: i8;
160+
asm!(".insn i 0x73, 0x4, {}, {}, 0x600", out(reg) value, in(reg) src);
161+
value
162+
}
163+
164+
/// Loads memory from hypervisor by unsigned byte integer
165+
///
166+
/// This instruction performs an explicit memory access as though `V=1`;
167+
/// i.e., with the address translation and protection, and the endianness, that apply to memory
168+
/// accesses in either VS-mode or VU-mode.
169+
///
170+
/// # Unsafety
171+
///
172+
/// This function accesses the virtual supervisor or user via a `HLV.BU` instruction which is effectively
173+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
174+
#[inline]
175+
pub unsafe fn hlv_bu(src: *const u8) -> u8 {
176+
let value: u8;
177+
asm!(".insn i 0x73, 0x4, {}, {}, 0x601", out(reg) value, in(reg) src);
178+
value
179+
}
180+
181+
/// Loads memory from hypervisor by signed half integer
182+
///
183+
/// This instruction performs an explicit memory access as though `V=1`;
184+
/// i.e., with the address translation and protection, and the endianness, that apply to memory
185+
/// accesses in either VS-mode or VU-mode.
186+
///
187+
/// # Unsafety
188+
///
189+
/// This function accesses the virtual supervisor or user via a `HLV.H` instruction which is effectively
190+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
191+
#[inline]
192+
pub unsafe fn hlv_h(src: *const i16) -> i16 {
193+
let value: i16;
194+
asm!(".insn i 0x73, 0x4, {}, {}, 0x640", out(reg) value, in(reg) src);
195+
value
196+
}
197+
198+
/// Loads memory from hypervisor by unsigned half integer
199+
///
200+
/// This instruction performs an explicit memory access as though `V=1`;
201+
/// i.e., with the address translation and protection, and the endianness, that apply to memory
202+
/// accesses in either VS-mode or VU-mode.
203+
///
204+
/// # Unsafety
205+
///
206+
/// This function accesses the virtual supervisor or user via a `HLV.HU` instruction which is effectively
207+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
208+
#[inline]
209+
pub unsafe fn hlv_hu(src: *const u16) -> u16 {
210+
let value: u16;
211+
asm!(".insn i 0x73, 0x4, {}, {}, 0x641", out(reg) value, in(reg) src);
212+
value
213+
}
214+
215+
/// Accesses instruction from hypervisor by unsigned half integer
216+
///
217+
/// This instruction performs an explicit memory access as though `V=1`;
218+
/// the memory being read must be executable in both stages of address translation,
219+
/// but read permission is not required.
220+
///
221+
/// # Unsafety
222+
///
223+
/// This function accesses the virtual supervisor or user via a `HLVX.HU` instruction which is effectively
224+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
225+
#[inline]
226+
pub unsafe fn hlvx_hu(src: *const u16) -> u16 {
227+
let insn: u16;
228+
asm!(".insn i 0x73, 0x4, {}, {}, 0x643", out(reg) insn, in(reg) src);
229+
insn
230+
}
231+
232+
/// Loads memory from hypervisor by signed word integer
233+
///
234+
/// This instruction performs an explicit memory access as though `V=1`;
235+
/// i.e., with the address translation and protection, and the endianness, that apply to memory
236+
/// accesses in either VS-mode or VU-mode.
237+
///
238+
/// # Unsafety
239+
///
240+
/// This function accesses the virtual supervisor or user via a `HLV.W` instruction which is effectively
241+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
242+
#[inline]
243+
pub unsafe fn hlv_w(src: *const i32) -> i32 {
244+
let value: i32;
245+
asm!(".insn i 0x73, 0x4, {}, {}, 0x680", out(reg) value, in(reg) src);
246+
value
247+
}
248+
249+
/// Accesses instruction from hypervisor by unsigned word integer
250+
///
251+
/// This instruction performs an explicit memory access as though `V=1`;
252+
/// the memory being read must be executable in both stages of address translation,
253+
/// but read permission is not required.
254+
///
255+
/// # Unsafety
256+
///
257+
/// This function accesses the virtual supervisor or user via a `HLVX.WU` instruction which is effectively
258+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
259+
#[inline]
260+
pub unsafe fn hlvx_wu(src: *const u32) -> u32 {
261+
let insn: u32;
262+
asm!(".insn i 0x73, 0x4, {}, {}, 0x683", out(reg) insn, in(reg) src);
263+
insn
264+
}
265+
266+
/// Stores memory from hypervisor by byte integer
267+
///
268+
/// This instruction performs an explicit memory access as though `V=1`;
269+
/// i.e., with the address translation and protection, and the endianness, that apply to memory
270+
/// accesses in either VS-mode or VU-mode.
271+
///
272+
/// # Unsafety
273+
///
274+
/// This function accesses the virtual supervisor or user via a `HSV.B` instruction which is effectively
275+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
276+
#[inline]
277+
pub unsafe fn hsv_b(dst: *mut i8, src: i8) {
278+
asm!(".insn r 0x73, 0x4, 0x31, x0, {}, {}", in(reg) dst, in(reg) src);
279+
}
280+
281+
/// Stores memory from hypervisor by half integer
282+
///
283+
/// This instruction performs an explicit memory access as though `V=1`;
284+
/// i.e., with the address translation and protection, and the endianness, that apply to memory
285+
/// accesses in either VS-mode or VU-mode.
286+
///
287+
/// # Unsafety
288+
///
289+
/// This function accesses the virtual supervisor or user via a `HSV.H` instruction which is effectively
290+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
291+
#[inline]
292+
pub unsafe fn hsv_h(dst: *mut i16, src: i16) {
293+
asm!(".insn r 0x73, 0x4, 0x33, x0, {}, {}", in(reg) dst, in(reg) src);
294+
}
295+
296+
/// Stores memory from hypervisor by word integer
297+
///
298+
/// This instruction performs an explicit memory access as though `V=1`;
299+
/// i.e., with the address translation and protection, and the endianness, that apply to memory
300+
/// accesses in either VS-mode or VU-mode.
301+
///
302+
/// # Unsafety
303+
///
304+
/// This function accesses the virtual supervisor or user via a `HSV.W` instruction which is effectively
305+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
306+
#[inline]
307+
pub unsafe fn hsv_w(dst: *mut i32, src: i32) {
308+
asm!(".insn r 0x73, 0x4, 0x35, x0, {}, {}", in(reg) dst, in(reg) src);
309+
}

crates/core_arch/src/riscv64/mod.rs

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//! RISC-V RV64 specific intrinsics
2+
use crate::arch::asm;
3+
4+
/// Loads memory from hypervisor by unsigned word integer
5+
///
6+
/// This instruction performs an explicit memory access as though `V=1`;
7+
/// i.e., with the address translation and protection, and the endianness, that apply to memory
8+
/// accesses in either VS-mode or VU-mode.
9+
///
10+
/// This operation is not available under RV32 base instruction set.
11+
///
12+
/// # Unsafety
13+
///
14+
/// This function accesses the virtual supervisor or user via a `HLV.WU` instruction which is effectively
15+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
16+
#[inline]
17+
pub unsafe fn hlv_wu(src: *const u32) -> u32 {
18+
let value: u32;
19+
asm!(".insn i 0x73, 0x4, {}, {}, 0x681", out(reg) value, in(reg) src);
20+
value
21+
}
22+
23+
/// Loads memory from hypervisor by unsigned double integer
24+
///
25+
/// This instruction performs an explicit memory access as though `V=1`;
26+
/// i.e., with the address translation and protection, and the endianness, that apply to memory
27+
/// accesses in either VS-mode or VU-mode.
28+
///
29+
/// This operation is not available under RV32 base instruction set.
30+
///
31+
/// # Unsafety
32+
///
33+
/// This function accesses the virtual supervisor or user via a `HLV.D` instruction which is effectively
34+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
35+
#[inline]
36+
pub unsafe fn hlv_d(src: *const i64) -> i64 {
37+
let value: i64;
38+
asm!(".insn i 0x73, 0x4, {}, {}, 0x6C0", out(reg) value, in(reg) src);
39+
value
40+
}
41+
42+
/// Stores memory from hypervisor by double integer
43+
///
44+
/// This instruction performs an explicit memory access as though `V=1`;
45+
/// i.e., with the address translation and protection, and the endianness, that apply to memory
46+
/// accesses in either VS-mode or VU-mode.
47+
///
48+
/// # Unsafety
49+
///
50+
/// This function accesses the virtual supervisor or user via a `HSV.D` instruction which is effectively
51+
/// an unreference to any memory address, thus is wrapped into an unsafe function.
52+
#[inline]
53+
pub unsafe fn hsv_d(dst: *mut i64, src: i64) {
54+
asm!(".insn r 0x73, 0x4, 0x37, x0, {}, {}", in(reg) dst, in(reg) src);
55+
}

0 commit comments

Comments
 (0)