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}