diff --git a/src/libc/bzero.src b/src/libc/bzero.src index e2c5a1ebb..d34490912 100644 --- a/src/libc/bzero.src +++ b/src/libc/bzero.src @@ -14,8 +14,8 @@ _bzero: add hl, sp ld bc, (hl) ; size inc bc - cpd ; dec hl - ret po ; zero size + cpd ; dec hl + ret po ; zero size dec hl dec hl ld de, (hl) ; buf @@ -31,20 +31,21 @@ else _bzero: ld hl, 6 add hl, sp - ld bc, (hl) + ld bc, (hl) ; BC = size dec hl dec hl dec hl - ld hl, (hl) - cpi - add hl, bc - ret c - dec hl + ld de, (hl) ; DE = dst + scf + sbc hl, hl + add hl, bc ; HL = size - 1 + ret nc ; size == 0 + add hl, de ; HL = dst + size - 1 ld (hl), 0 - ret po - push hl - pop de - dec de + cpd ; HL = dst + size - 2, BC = size - 1 + ex de, hl ; DE = dst + size - 2, HL = dst + ret po ; return if size == 1 + add hl, bc ; HL = dst + size - 1 lddr ret diff --git a/src/libc/memset.src b/src/libc/memset.src index 8a38207d9..6aefd9d3e 100644 --- a/src/libc/memset.src +++ b/src/libc/memset.src @@ -5,19 +5,20 @@ public _memset _memset: - ld iy, 0 + ld iy, -1 add iy, sp - ld hl, (iy + 3) - ld bc, (iy + 9) - cpi - add hl, bc - ret c - dec hl - ld e, (iy + 6) - ld (hl), e - ret po - push hl - pop de - dec de + ld bc, (iy + 10) ; BC = size + sbc hl, hl ; always resets overflow + add hl, bc ; HL = size - 1 + ld de, (iy + 4) ; DE = dst + jr nc, .zero_size + ld a, (iy + 7) + add hl, de ; HL = dst + size - 1 + ld (hl), a + cpd ; HL = dst + size - 2, BC = size - 1 +.zero_size: + ex de, hl ; DE = dst + size - 2, HL = dst + ret po ; return if size == 1 + add hl, bc ; HL = dst + size - 1 lddr ret diff --git a/src/libc/wmemset.src b/src/libc/wmemset.src index 58f1e3835..92b34b3ce 100644 --- a/src/libc/wmemset.src +++ b/src/libc/wmemset.src @@ -6,33 +6,30 @@ ; wchar_t *wmemset(wchar_t *dst, wchar_t ch, size_t count) _wmemset: - pop iy, hl, de, bc - push bc, de, hl, iy - ; BC = count - ; DE = ch - ; HL = dst - - ; count *= sizeof(wchar_t) - cpi ; hl++ bc-- - add hl, bc ; HL = (dst + 1) + (count - 1) = dst + count - ret c ; bc is zero - add hl, bc ; HL = dst + count + (count - 1) = dst + 2 * count - 1 - - ; hl += (count - 1) * 2 + 1 - ; count -= 2 - ld (hl), d ; upper 8 bits - dec hl - ld (hl), e ; lower 8 bits - ret po ; only one element needs to be written - - ; write multiple elements - push hl - pop de - inc hl - dec de - - push bc + ld iy, -1 + add iy, sp + ld bc, (iy + 10) ; BC = count + sbc hl, hl + add hl, bc ; HL = count - 1 + ex de, hl ; DE = count - 1 + ld hl, (iy + 4) ; HL = dst + ret nc ; count == 0 + add hl, bc ; HL = dst + count + add hl, de ; HL = dst + 2 * count - 1 + ex de, hl ; DE = dst + 2 * count - 1 + lea hl, iy + 8 ; HL = &upper_byte + ldd + ; HL = &lower_byte + ; DE = dst + 2 * count - 2 + ld a, (hl) + ld (de), a + push de + pop hl + ret po ; count == 1 + inc hl ; HL = dst + 2 * count - 1 + dec de ; DE = dst + 2 * count - 3 ; use lddr twice + push bc lddr pop bc lddr diff --git a/test/standalone/asprintf_fprintf/src/main.c b/test/standalone/asprintf_fprintf/src/main.c index 6f17344fc..181d5f8f7 100644 --- a/test/standalone/asprintf_fprintf/src/main.c +++ b/test/standalone/asprintf_fprintf/src/main.c @@ -521,6 +521,15 @@ int mempcpy_test(void) { int bzero_test(void) { char truth[32]; char data[32]; + + // test zero size cases + C(T_memset(NULL_ptr, 0xCE, 0) == NULL_ptr); + C(T_memset((void*)0xFFFFFF, 0xCE, 0) == (void*)0xFFFFFF); + C(T_memset((void*)0x000001, 0xCE, 0) == (void*)0x000001); + T_bzero(NULL_ptr, 0); + T_bzero((void*)0xFFFFFF, 0); + T_bzero((void*)0x000001, 0); + T_memset(data, 0x8F, sizeof(data)); T_memset(&truth[ 0], 0x8F, 8); T_memset(&truth[ 2], 0x00, 1); diff --git a/test/standalone/wide_char/src/main.c b/test/standalone/wide_char/src/main.c index 028e978f0..c726e6370 100644 --- a/test/standalone/wide_char/src/main.c +++ b/test/standalone/wide_char/src/main.c @@ -24,7 +24,7 @@ extern wchar_t * const PTR_000000; extern wchar_t * const PTR_FFFFFF; -#if 0 +#if 1 int T_wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n) __NOEXCEPT __attribute__((__pure__)); wchar_t * T_wmemchr(const wchar_t *ptr, int ch, size_t count) __NOEXCEPT __attribute__((__pure__)); @@ -182,6 +182,10 @@ int test_wmemset(void) { test_printf("%p != %p\n", ptr, (void*)0xC0FFEE); return __LINE__; } + C(wmemset(PTR_000000, 0x71CE, 0) == PTR_000000); + C(wmemset(PTR_FFFFFF, 0x71CE, 0) == PTR_FFFFFF); + C(wmemset((void*)0x000001, 0x71CE, 0) == (void*)0x000001); + wchar_t data[192 + 1]; memset(data, 0xBC, sizeof(data)); wmemset(wmemset(&data[ 0], 0x0012, 64) + 64, 0x0012, 64); @@ -194,7 +198,7 @@ int test_wmemset(void) { test_printf("%p != %p\n", res, &data[64]); return __LINE__; } - + wchar_t truth[192 + 1]; memset(truth, 0xDE, sizeof(truth)); C(&truth[ 0] == wmemset(&truth[ 0], 0x0012, 64)); @@ -230,7 +234,7 @@ int test_wmemset(void) { int test_wmemmove(void) { wchar_t move_str[] = {0x000F, 0x111F, 0x222F, 0x333F, 0x444F, 0x555F, 0x666F, 0x777F, 0x888F, 0x999F}; - const wchar_t truth_str[] = + const wchar_t truth_str[] = {0x999F, 0x333F, 0x444F, 0x444F, 0x555F, 0x444F, 0x555F, 0x666F, 0x888F, 0x999F}; C(move_str + 5 == wmemmove(move_str + 5, move_str + 4, 3)); C(move_str + 3 == wmemmove(move_str + 3, move_str + 3, 0)); diff --git a/test/standalone/wide_char/src/rename.asm b/test/standalone/wide_char/src/rename.asm index 0719b092e..fce6d2c5f 100644 --- a/test/standalone/wide_char/src/rename.asm +++ b/test/standalone/wide_char/src/rename.asm @@ -9,3 +9,20 @@ _PTR_000000: public _PTR_FFFFFF _PTR_FFFFFF: db $FF, $FF, $FF + + section .text + + public _T_wmemset, _T_wmemcpy, _T_wmemmove, _T_wmemcmp, _T_wmemchr + public _T_wcslen, _T_wcsnlen + +_T_wmemset := _wmemset +_T_wmemcpy := _wmemcpy +_T_wmemmove := _wmemmove +_T_wmemcmp := _wmemcmp +_T_wmemchr := _wmemchr + +_T_wcslen := _wcslen +_T_wcsnlen := _wcsnlen + + extern _wmemset, _wmemcpy, _wmemmove, _wmemcmp, _wmemchr + extern _wcslen, _wcsnlen