hare

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

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

rt: copy by words in memcpy

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

Diffstat:
Mrt/memcpy.ha | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Art/memfunc_ptr.ha | 9+++++++++
Mscripts/gen-stdlib | 2++
Mstdlib.mk | 4++++
4 files changed, 95 insertions(+), 4 deletions(-)

diff --git a/rt/memcpy.ha b/rt/memcpy.ha @@ -1,9 +1,85 @@ // License: MPL-2.0 // (c) 2021 Drew DeVault <sir@cmpwn.com> -export fn memcpy(dest: *opaque, src: *const opaque, amt: size) void = { - let a = dest: *[*]u8, b = src: *const [*]u8; - for (let i = 0z; i < amt; i += 1) { - a[i] = b[i]; +def MOD32 = size(u32) - 1; + +export fn memcpy(dest: *opaque, src: *const opaque, n: size) void = { + // implementation adapted from musl libc + + let d = memfunc_ptr { byte = dest: *[*]u8 }; + let s = memfunc_ptr { byte = src: *[*]u8 }; + + // copy bytes until src pointer is u32-aligned + for (s.uptr & MOD32 != 0 && 0 < n; n -= 1) { + d.byte[0] = s.byte[0]; + d.uptr += 1; + s.uptr += 1; + }; + + // if dest is u32-aligned with src, copy as batches of u32s + if (d.uptr & MOD32 == 0) { + for (16 <= n; n -= 16) { + d.quad[0] = s.quad[0]; + d.quad[1] = s.quad[1]; + d.quad[2] = s.quad[2]; + d.quad[3] = s.quad[3]; + d.uptr += 16; + s.uptr += 16; + }; + if (n & 8 != 0) { + d.quad[0] = s.quad[0]; + d.quad[1] = s.quad[1]; + d.uptr += 8; + s.uptr += 8; + }; + if (n & 4 != 0) { + d.quad[0] = s.quad[0]; + d.uptr += 4; + s.uptr += 4; + }; + } else { + // TODO: musl uses some byte-order-dependent code here + // which could be incorporated at some point. + for (16 <= n; n -= 16) { + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + }; + if (n & 8 != 0) { + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + }; + if (n & 4 != 0) { + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + }; + }; + if (n & 2 != 0) { + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + d.byte[0] = s.byte[0]; d.uptr += 1; s.uptr += 1; + }; + if (n & 1 != 0) { + d.byte[0] = s.byte[0]; }; }; diff --git a/rt/memfunc_ptr.ha b/rt/memfunc_ptr.ha @@ -0,0 +1,9 @@ +// License: MPL-2.0 + +type memfunc_ptr = union { + byte: *[*]u8, + quad: *[*]u32, + octs: *[*]u64, + sz: *[*]size, + uptr: uintptr, +}; diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -40,6 +40,7 @@ gensrcs_rt() { jmp.ha \ malloc.ha \ memcpy.ha \ + memfunc_ptr.ha \ memmove.ha \ memset.ha \ strcmp.ha \ @@ -66,6 +67,7 @@ gensrcs_rt() { jmp.ha \ malloc.ha \ memcpy.ha \ + memfunc_ptr.ha \ memmove.ha \ memset.ha \ strcmp.ha \ diff --git a/stdlib.mk b/stdlib.mk @@ -24,6 +24,7 @@ stdlib_rt_linux_srcs = \ $(STDLIB)/rt/jmp.ha \ $(STDLIB)/rt/malloc.ha \ $(STDLIB)/rt/memcpy.ha \ + $(STDLIB)/rt/memfunc_ptr.ha \ $(STDLIB)/rt/memmove.ha \ $(STDLIB)/rt/memset.ha \ $(STDLIB)/rt/strcmp.ha \ @@ -53,6 +54,7 @@ stdlib_rt_freebsd_srcs = \ $(STDLIB)/rt/jmp.ha \ $(STDLIB)/rt/malloc.ha \ $(STDLIB)/rt/memcpy.ha \ + $(STDLIB)/rt/memfunc_ptr.ha \ $(STDLIB)/rt/memmove.ha \ $(STDLIB)/rt/memset.ha \ $(STDLIB)/rt/strcmp.ha \ @@ -2466,6 +2468,7 @@ testlib_rt_linux_srcs = \ $(STDLIB)/rt/jmp.ha \ $(STDLIB)/rt/malloc.ha \ $(STDLIB)/rt/memcpy.ha \ + $(STDLIB)/rt/memfunc_ptr.ha \ $(STDLIB)/rt/memmove.ha \ $(STDLIB)/rt/memset.ha \ $(STDLIB)/rt/strcmp.ha \ @@ -2496,6 +2499,7 @@ testlib_rt_freebsd_srcs = \ $(STDLIB)/rt/jmp.ha \ $(STDLIB)/rt/malloc.ha \ $(STDLIB)/rt/memcpy.ha \ + $(STDLIB)/rt/memfunc_ptr.ha \ $(STDLIB)/rt/memmove.ha \ $(STDLIB)/rt/memset.ha \ $(STDLIB)/rt/strcmp.ha \