memcpy.ha (2751B)
1 // SPDX-License-Identifier: MPL-2.0 2 // (c) Hare authors <https://harelang.org> 3 4 def MOD32 = size(u32) - 1; 5 6 export fn memcpy(dest: *opaque, src: *const opaque, n: size) void = { 7 // implementation adapted from musl libc 8 9 let d = memfunc_ptr { byte = dest: *[*]u8 }; 10 let s = memfunc_ptr { byte = src: *[*]u8 }; 11 12 // copy bytes until src pointer is u32-aligned 13 for (s.uptr & MOD32 != 0 && 0 < n; n -= 1) { 14 d.byte[0] = s.byte[0]; 15 d.uptr += 1; 16 s.uptr += 1; 17 }; 18 19 // if dest is u32-aligned with src, copy as batches of u32s 20 if (d.uptr & MOD32 == 0) { 21 for (16 <= n; n -= 16) { 22 d.quad[0] = s.quad[0]; 23 d.quad[1] = s.quad[1]; 24 d.quad[2] = s.quad[2]; 25 d.quad[3] = s.quad[3]; 26 d.uptr += 16; 27 s.uptr += 16; 28 }; 29 if (n & 8 != 0) { 30 d.quad[0] = s.quad[0]; 31 d.quad[1] = s.quad[1]; 32 d.uptr += 8; 33 s.uptr += 8; 34 }; 35 if (n & 4 != 0) { 36 d.quad[0] = s.quad[0]; 37 d.uptr += 4; 38 s.uptr += 4; 39 }; 40 } else { 41 // TODO: musl uses some byte-order-dependent code here 42 // which could be incorporated at some point. 43 for (16 <= n; n -= 16) { 44 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 45 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 46 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 47 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 48 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 49 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 50 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 51 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 52 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 53 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 54 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 55 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 56 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 57 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 58 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 59 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 60 }; 61 if (n & 8 != 0) { 62 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 63 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 64 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 65 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 66 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 67 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 68 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 69 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 70 }; 71 if (n & 4 != 0) { 72 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 73 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 74 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 75 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 76 }; 77 }; 78 if (n & 2 != 0) { 79 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 80 d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; 81 }; 82 if (n & 1 != 0) { 83 d.byte[0] = s.byte[0]; 84 }; 85 };