diff --git a/std/assembly/util/memory.ts b/std/assembly/util/memory.ts index 77981ea783..26d42b883b 100644 --- a/std/assembly/util/memory.ts +++ b/std/assembly/util/memory.ts @@ -1,150 +1,143 @@ export function memcpy(dest: usize, src: usize, n: usize): void { // see: musl/src/string/memcpy.c - if (ASC_SHRINK_LEVEL > 1) { - while (n) { - store(dest++, load(src++)); - --n; - } - } else { - let w: u32, x: u32; + var w: u32, x: u32; - // copy 1 byte each until src is aligned to 4 bytes - while (n && (src & 3)) { + // copy 1 byte each until src is aligned to 4 bytes + while (n && (src & 3)) { + store(dest++, load(src++)); + n--; + } + + // if dst is aligned to 4 bytes as well, copy 4 bytes each + if ((dest & 3) == 0) { + while (n >= 16) { + store(dest , load(src )); + store(dest + 4, load(src + 4)); + store(dest + 8, load(src + 8)); + store(dest + 12, load(src + 12)); + src += 16; dest += 16; n -= 16; + } + if (n & 8) { + store(dest , load(src )); + store(dest + 4, load(src + 4)); + dest += 8; src += 8; + } + if (n & 4) { + store(dest, load(src)); + dest += 4; src += 4; + } + if (n & 2) { // drop to 2 bytes each + store(dest, load(src)); + dest += 2; src += 2; + } + if (n & 1) { // drop to 1 byte store(dest++, load(src++)); - n--; } + return; + } - // if dst is aligned to 4 bytes as well, copy 4 bytes each - if ((dest & 3) == 0) { - while (n >= 16) { - store(dest , load(src )); - store(dest + 4, load(src + 4)); - store(dest + 8, load(src + 8)); - store(dest + 12, load(src + 12)); - src += 16; dest += 16; n -= 16; - } - if (n & 8) { - store(dest , load(src )); - store(dest + 4, load(src + 4)); - dest += 8; src += 8; - } - if (n & 4) { - store(dest, load(src)); - dest += 4; src += 4; - } - if (n & 2) { // drop to 2 bytes each - store(dest, load(src)); - dest += 2; src += 2; - } - if (n & 1) { // drop to 1 byte + // if dst is not aligned to 4 bytes, use alternating shifts to copy 4 bytes each + // doing shifts if faster when copying enough bytes (here: 32 or more) + if (n >= 32) { + switch (dest & 3) { + // known to be != 0 + case 1: { + w = load(src); store(dest++, load(src++)); - } - return; - } - - // if dst is not aligned to 4 bytes, use alternating shifts to copy 4 bytes each - // doing shifts if faster when copying enough bytes (here: 32 or more) - if (n >= 32) { - switch (dest & 3) { - // known to be != 0 - case 1: { - w = load(src); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - n -= 3; - while (n >= 17) { - x = load(src + 1); - store(dest, w >> 24 | x << 8); - w = load(src + 5); - store(dest + 4, x >> 24 | w << 8); - x = load(src + 9); - store(dest + 8, w >> 24 | x << 8); - w = load(src + 13); - store(dest + 12, x >> 24 | w << 8); - src += 16; dest += 16; n -= 16; - } - break; + store(dest++, load(src++)); + store(dest++, load(src++)); + n -= 3; + while (n >= 17) { + x = load(src + 1); + store(dest, w >> 24 | x << 8); + w = load(src + 5); + store(dest + 4, x >> 24 | w << 8); + x = load(src + 9); + store(dest + 8, w >> 24 | x << 8); + w = load(src + 13); + store(dest + 12, x >> 24 | w << 8); + src += 16; dest += 16; n -= 16; } - case 2: { - w = load(src); - store(dest++, load(src++)); - store(dest++, load(src++)); - n -= 2; - while (n >= 18) { - x = load(src + 2); - store(dest, w >> 16 | x << 16); - w = load(src + 6); - store(dest + 4, x >> 16 | w << 16); - x = load(src + 10); - store(dest + 8, w >> 16 | x << 16); - w = load(src + 14); - store(dest + 12, x >> 16 | w << 16); - src += 16; dest += 16; n -= 16; - } - break; + break; + } + case 2: { + w = load(src); + store(dest++, load(src++)); + store(dest++, load(src++)); + n -= 2; + while (n >= 18) { + x = load(src + 2); + store(dest, w >> 16 | x << 16); + w = load(src + 6); + store(dest + 4, x >> 16 | w << 16); + x = load(src + 10); + store(dest + 8, w >> 16 | x << 16); + w = load(src + 14); + store(dest + 12, x >> 16 | w << 16); + src += 16; dest += 16; n -= 16; } - case 3: { - w = load(src); - store(dest++, load(src++)); - n -= 1; - while (n >= 19) { - x = load(src + 3); - store(dest, w >> 8 | x << 24); - w = load(src + 7); - store(dest + 4, x >> 8 | w << 24); - x = load(src + 11); - store(dest + 8, w >> 8 | x << 24); - w = load(src + 15); - store(dest + 12, x >> 8 | w << 24); - src += 16; dest += 16; n -= 16; - } - break; + break; + } + case 3: { + w = load(src); + store(dest++, load(src++)); + n -= 1; + while (n >= 19) { + x = load(src + 3); + store(dest, w >> 8 | x << 24); + w = load(src + 7); + store(dest + 4, x >> 8 | w << 24); + x = load(src + 11); + store(dest + 8, w >> 8 | x << 24); + w = load(src + 15); + store(dest + 12, x >> 8 | w << 24); + src += 16; dest += 16; n -= 16; } + break; } } + } - // copy remaining bytes one by one - if (n & 16) { - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - } - if (n & 8) { - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - } - if (n & 4) { - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - store(dest++, load(src++)); - } - if (n & 2) { - store(dest++, load(src++)); - store(dest++, load(src++)); - } - if (n & 1) { - store(dest++, load(src++)); - } + // copy remaining bytes one by one + if (n & 16) { + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + } + if (n & 8) { + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + } + if (n & 4) { + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + store(dest++, load(src++)); + } + if (n & 2) { + store(dest++, load(src++)); + store(dest++, load(src++)); + } + if (n & 1) { + store(dest++, load(src++)); } } @@ -159,17 +152,19 @@ export function memmove(dest: usize, src: usize, n: usize): void { // see: musl/ } } if (dest < src) { - if ((src & 7) == (dest & 7)) { - while (dest & 7) { - if (!n) return; - --n; - store(dest++, load(src++)); - } - while (n >= 8) { - store(dest, load(src)); - n -= 8; - dest += 8; - src += 8; + if (ASC_SHRINK_LEVEL < 2) { + if ((src & 7) == (dest & 7)) { + while (dest & 7) { + if (!n) return; + --n; + store(dest++, load(src++)); + } + while (n >= 8) { + store(dest, load(src)); + n -= 8; + dest += 8; + src += 8; + } } } while (n) { @@ -177,14 +172,16 @@ export function memmove(dest: usize, src: usize, n: usize): void { // see: musl/ --n; } } else { - if ((src & 7) == (dest & 7)) { - while ((dest + n) & 7) { - if (!n) return; - store(dest + --n, load(src + n)); - } - while (n >= 8) { - n -= 8; - store(dest + n, load(src + n)); + if (ASC_SHRINK_LEVEL < 2) { + if ((src & 7) == (dest & 7)) { + while ((dest + n) & 7) { + if (!n) return; + store(dest + --n, load(src + n)); + } + while (n >= 8) { + n -= 8; + store(dest + n, load(src + n)); + } } } while (n) {