minimal_rt/arch/x86_64/intrinsics.rs
1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! x86_64 intrinsics.
5
6#![cfg_attr(minimal_rt, expect(clippy::missing_safety_doc))]
7
8/// Hand rolled implementation of memset.
9#[cfg(minimal_rt)]
10// SAFETY: The minimal_rt_build crate ensures that when this code is compiled
11// there is no libc for this to conflict with.
12#[unsafe(no_mangle)]
13unsafe extern "C" fn memset(mut ptr: *mut u8, val: i32, len: usize) -> *mut u8 {
14 // SAFETY: The caller guarantees that the pointer and length are correct.
15 unsafe {
16 core::arch::asm!(r#"
17 cld
18 rep stosb
19 "#,
20 in("rax") val,
21 in("rcx") len,
22 inout("rdi") ptr);
23 }
24 ptr
25}
26
27/// Hand rolled implementation of memcpy.
28#[cfg(minimal_rt)]
29// SAFETY: The minimal_rt_build crate ensures that when this code is compiled
30// there is no libc for this to conflict with.
31#[unsafe(no_mangle)]
32unsafe extern "C" fn memcpy(mut dest: *mut u8, src: *const u8, len: usize) -> *mut u8 {
33 // SAFETY: The caller guarantees that the pointers and length are correct.
34 unsafe {
35 core::arch::asm!(r#"
36 cld
37 rep movsb
38 "#,
39 in("rsi") src,
40 in("rcx") len,
41 inout("rdi") dest);
42 }
43 dest
44}
45
46/// Causes a processor fault.
47pub fn fault() -> ! {
48 // SAFETY: ud2 is always safe, and will cause the function to diverge.
49 unsafe {
50 core::arch::asm!("ud2");
51 core::hint::unreachable_unchecked()
52 }
53}
54
55/// Spins forever, preserving some context in the registers.
56pub fn dead_loop(code0: u64, code1: u64, code2: u64) -> ! {
57 // SAFETY: This spin loop has no safety conditions.
58 unsafe {
59 core::arch::asm!("1: jmp 1b", in ("rdi") code0, in ("rsi") code1, in ("rax") code2, options(att_syntax));
60 core::hint::unreachable_unchecked()
61 }
62}