| 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 | // memcpy/memmove/memset have optimized implementations on some architectures |
| 7 | #[cfg_attr ( |
| 8 | all(not(feature = "no-asm" ), target_arch = "x86_64" ), |
| 9 | path = "x86_64.rs" |
| 10 | )] |
| 11 | mod impls; |
| 12 | |
| 13 | intrinsics! { |
| 14 | #[mem_builtin] |
| 15 | pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { |
| 16 | impls::copy_forward(dest, src, n); |
| 17 | dest |
| 18 | } |
| 19 | |
| 20 | #[mem_builtin] |
| 21 | pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 { |
| 22 | let delta = (dest as usize).wrapping_sub(src as usize); |
| 23 | if delta >= n { |
| 24 | // We can copy forwards because either dest is far enough ahead of src, |
| 25 | // or src is ahead of dest (and delta overflowed). |
| 26 | impls::copy_forward(dest, src, n); |
| 27 | } else { |
| 28 | impls::copy_backward(dest, src, n); |
| 29 | } |
| 30 | dest |
| 31 | } |
| 32 | |
| 33 | #[mem_builtin] |
| 34 | pub unsafe extern "C" fn memset(s: *mut u8, c: core::ffi::c_int, n: usize) -> *mut u8 { |
| 35 | impls::set_bytes(s, c as u8, n); |
| 36 | s |
| 37 | } |
| 38 | |
| 39 | #[mem_builtin] |
| 40 | pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> core::ffi::c_int { |
| 41 | impls::compare_bytes(s1, s2, n) |
| 42 | } |
| 43 | |
| 44 | #[mem_builtin] |
| 45 | pub unsafe extern "C" fn bcmp(s1: *const u8, s2: *const u8, n: usize) -> core::ffi::c_int { |
| 46 | memcmp(s1, s2, n) |
| 47 | } |
| 48 | |
| 49 | #[mem_builtin] |
| 50 | pub unsafe extern "C" fn strlen(s: *const core::ffi::c_char) -> usize { |
| 51 | impls::c_string_length(s) |
| 52 | } |
| 53 | } |
| 54 | |