hare

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

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 };