hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 9c2d4ba4dafa4679127edcb26078a9ddb8695010
parent e00d4a9b82076fde6a6f032753518ee37715bcd4
Author: Autumn! <autumnull@posteo.net>
Date:   Thu,  7 Sep 2023 14:47:23 +0000

rt: copy by words in memmove

Signed-off-by: Autumn! <autumnull@posteo.net>

Diffstat:
Mrt/memmove.ha | 63++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 54 insertions(+), 9 deletions(-)

diff --git a/rt/memmove.ha b/rt/memmove.ha @@ -1,19 +1,64 @@ // License: MPL-2.0 // (c) 2021 Drew DeVault <sir@cmpwn.com> +def SZSZ = size(size); +def MODSZ = size(size) - 1; + export fn memmove(dest: *opaque, src: *const opaque, n: size) void = { - let d = dest: *[*]u8, s = src: *const [*]u8; - if (d: uintptr == s: uintptr) { - return; - }; + // implementation adapted from musl libc + + let d = memfunc_ptr { byte = dest: *[*]u8 }; + let s = memfunc_ptr { byte = src: *[*]u8 }; - if (d: uintptr < s: uintptr) { - for (let i = 0z; i < n; i += 1) { - d[i] = s[i]; + if (d.uptr == s.uptr) return; + // equivalent to n <= abs(src - dest) + if (s.uptr - d.uptr - n <= -2*n) return memcpy(dest, src, n); + + if (d.uptr < s.uptr) { + // if alignment matches, copy the majority as []size + if (s.uptr & MODSZ == d.uptr & MODSZ) { + // use u8 until we reach a word boundary + for (0 < d.uptr & MODSZ) { + if (n == 0) return else n -= 1; + d.byte[0] = s.byte[0]; + d.uptr += 1; + s.uptr += 1; + }; + for (SZSZ <= n; n -= SZSZ) { + d.sz[0] = s.sz[0]; + // TODO: should be +=, blocked on compiler bug + d.uptr = d.uptr + SZSZ; + s.uptr = s.uptr + SZSZ; + }; + }; + for (0 < n; n -= 1) { + d.byte[0] = s.byte[0]; + d.uptr += 1; + s.uptr += 1; }; } else { - for (let i = 0z; i < n; i += 1) { - d[n - i - 1] = s[n - i - 1]; + d.uptr = d.uptr + n; + s.uptr = s.uptr + n; + // if alignment matches, copy the majority as []size + if (s.uptr & MODSZ == d.uptr & MODSZ) { + // use u8 until we reach a word boundary + for (0 < d.uptr & MODSZ) { + if (n == 0) return else n -= 1; + d.uptr -= 1; + s.uptr -= 1; + d.byte[0] = s.byte[0]; + }; + for (SZSZ <= n; n -= SZSZ) { + // TODO: should be -=, blocked on compiler bug + d.uptr = d.uptr - SZSZ; + s.uptr = s.uptr - SZSZ; + d.sz[0] = s.sz[0]; + }; + }; + for (0 < n; n -= 1) { + d.uptr -= 1; + s.uptr -= 1; + d.byte[0] = s.byte[0]; }; }; };