1 | // Trying to satisfy clippy here is hopeless |
2 | #![allow (clippy::style)] |
3 | // FIXME(e2024): this eventually needs to be removed. |
4 | #![allow (unsafe_op_in_unsafe_fn)] |
5 | |
6 | #[allow (warnings)] |
7 | #[cfg (target_pointer_width = "16" )] |
8 | type c_int = i16; |
9 | #[allow (warnings)] |
10 | #[cfg (not(target_pointer_width = "16" ))] |
11 | type c_int = i32; |
12 | |
13 | // memcpy/memmove/memset have optimized implementations on some architectures |
14 | #[cfg_attr ( |
15 | all(not(feature = "no-asm" ), target_arch = "x86_64" ), |
16 | path = "x86_64.rs" |
17 | )] |
18 | mod impls; |
19 | |
20 | intrinsics! { |
21 | #[mem_builtin] |
22 | pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { |
23 | impls::copy_forward(dest, src, n); |
24 | dest |
25 | } |
26 | |
27 | #[mem_builtin] |
28 | pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { |
29 | let delta = (dest as usize).wrapping_sub(src as usize); |
30 | if delta >= n { |
31 | // We can copy forwards because either dest is far enough ahead of src, |
32 | // or src is ahead of dest (and delta overflowed). |
33 | impls::copy_forward(dest, src, n); |
34 | } else { |
35 | impls::copy_backward(dest, src, n); |
36 | } |
37 | dest |
38 | } |
39 | |
40 | #[mem_builtin] |
41 | pub unsafe extern "C" fn memset(s: *mut u8, c: crate::mem::c_int, n: usize) -> *mut u8 { |
42 | impls::set_bytes(s, c as u8, n); |
43 | s |
44 | } |
45 | |
46 | #[mem_builtin] |
47 | pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 { |
48 | impls::compare_bytes(s1, s2, n) |
49 | } |
50 | |
51 | #[mem_builtin] |
52 | pub unsafe extern "C" fn bcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 { |
53 | memcmp(s1, s2, n) |
54 | } |
55 | |
56 | #[mem_builtin] |
57 | pub unsafe extern "C" fn strlen(s: *const core::ffi::c_char) -> usize { |
58 | impls::c_string_length(s) |
59 | } |
60 | } |
61 | |