Skip to content

Commit a4fcb28

Browse files
committed
fixed behavior of memset((void*)-1, ch, 0) along with bzero and wmemset
1 parent a494909 commit a4fcb28

File tree

6 files changed

+83
-54
lines changed

6 files changed

+83
-54
lines changed

src/libc/bzero.src

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ _bzero:
1414
add hl, sp
1515
ld bc, (hl) ; size
1616
inc bc
17-
cpd ; dec hl
18-
ret po ; zero size
17+
cpd ; dec hl
18+
ret po ; zero size
1919
dec hl
2020
dec hl
2121
ld de, (hl) ; buf
@@ -31,20 +31,21 @@ else
3131
_bzero:
3232
ld hl, 6
3333
add hl, sp
34-
ld bc, (hl)
34+
ld bc, (hl) ; BC = size
3535
dec hl
3636
dec hl
3737
dec hl
38-
ld hl, (hl)
39-
cpi
40-
add hl, bc
41-
ret c
42-
dec hl
38+
ld de, (hl) ; DE = dst
39+
scf
40+
sbc hl, hl
41+
add hl, bc ; HL = size - 1
42+
ret nc ; size == 0
43+
add hl, de ; HL = dst + size - 1
4344
ld (hl), 0
44-
ret po
45-
push hl
46-
pop de
47-
dec de
45+
cpd ; HL = dst + size - 2, BC = size - 1
46+
ex de, hl ; DE = dst + size - 2, HL = dst
47+
ret po ; return if size == 1
48+
add hl, bc ; HL = dst + size - 1
4849
lddr
4950
ret
5051

src/libc/memset.src

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,20 @@
55
public _memset
66

77
_memset:
8-
ld iy, 0
8+
ld iy, -1
99
add iy, sp
10-
ld hl, (iy + 3)
11-
ld bc, (iy + 9)
12-
cpi
13-
add hl, bc
14-
ret c
15-
dec hl
16-
ld e, (iy + 6)
17-
ld (hl), e
18-
ret po
19-
push hl
20-
pop de
21-
dec de
10+
ld bc, (iy + 10) ; BC = size
11+
sbc hl, hl ; always resets overflow
12+
add hl, bc ; HL = size - 1
13+
ld de, (iy + 4) ; DE = dst
14+
jr nc, .zero_size
15+
ld a, (iy + 7)
16+
add hl, de ; HL = dst + size - 1
17+
ld (hl), a
18+
cpd ; HL = dst + size - 2, BC = size - 1
19+
.zero_size:
20+
ex de, hl ; DE = dst + size - 2, HL = dst
21+
ret po ; return if size == 1
22+
add hl, bc ; HL = dst + size - 1
2223
lddr
2324
ret

src/libc/wmemset.src

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,30 @@
66

77
; wchar_t *wmemset(wchar_t *dst, wchar_t ch, size_t count)
88
_wmemset:
9-
pop iy, hl, de, bc
10-
push bc, de, hl, iy
11-
; BC = count
12-
; DE = ch
13-
; HL = dst
14-
15-
; count *= sizeof(wchar_t)
16-
cpi ; hl++ bc--
17-
add hl, bc ; HL = (dst + 1) + (count - 1) = dst + count
18-
ret c ; bc is zero
19-
add hl, bc ; HL = dst + count + (count - 1) = dst + 2 * count - 1
20-
21-
; hl += (count - 1) * 2 + 1
22-
; count -= 2
23-
ld (hl), d ; upper 8 bits
24-
dec hl
25-
ld (hl), e ; lower 8 bits
26-
ret po ; only one element needs to be written
27-
28-
; write multiple elements
29-
push hl
30-
pop de
31-
inc hl
32-
dec de
33-
34-
push bc
9+
ld iy, -1
10+
add iy, sp
11+
ld bc, (iy + 10) ; BC = count
12+
sbc hl, hl
13+
add hl, bc ; HL = count - 1
14+
ex de, hl ; DE = count - 1
15+
ld hl, (iy + 4) ; HL = dst
16+
ret nc ; count == 0
17+
add hl, bc ; HL = dst + count
18+
add hl, de ; HL = dst + 2 * count - 1
19+
ex de, hl ; DE = dst + 2 * count - 1
20+
lea hl, iy + 8 ; HL = &upper_byte
21+
ldd
22+
; HL = &lower_byte
23+
; DE = dst + 2 * count - 2
24+
ld a, (hl)
25+
ld (de), a
26+
push de
27+
pop hl
28+
ret po ; count == 1
29+
inc hl ; HL = dst + 2 * count - 1
30+
dec de ; DE = dst + 2 * count - 3
3531
; use lddr twice
32+
push bc
3633
lddr
3734
pop bc
3835
lddr

test/standalone/asprintf_fprintf/src/main.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,15 @@ int mempcpy_test(void) {
521521
int bzero_test(void) {
522522
char truth[32];
523523
char data[32];
524+
525+
// test zero size cases
526+
C(T_memset(NULL_ptr, 0xCE, 0) == NULL_ptr);
527+
C(T_memset((void*)0xFFFFFF, 0xCE, 0) == (void*)0xFFFFFF);
528+
C(T_memset((void*)0x000001, 0xCE, 0) == (void*)0x000001);
529+
T_bzero(NULL_ptr, 0);
530+
T_bzero((void*)0xFFFFFF, 0);
531+
T_bzero((void*)0x000001, 0);
532+
524533
T_memset(data, 0x8F, sizeof(data));
525534
T_memset(&truth[ 0], 0x8F, 8);
526535
T_memset(&truth[ 2], 0x00, 1);

test/standalone/wide_char/src/main.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
extern wchar_t * const PTR_000000;
2525
extern wchar_t * const PTR_FFFFFF;
2626

27-
#if 0
27+
#if 1
2828

2929
int T_wmemcmp(const wchar_t *s1, const wchar_t *s2, size_t n) __NOEXCEPT __attribute__((__pure__));
3030
wchar_t * T_wmemchr(const wchar_t *ptr, int ch, size_t count) __NOEXCEPT __attribute__((__pure__));
@@ -182,6 +182,10 @@ int test_wmemset(void) {
182182
test_printf("%p != %p\n", ptr, (void*)0xC0FFEE);
183183
return __LINE__;
184184
}
185+
C(wmemset(PTR_000000, 0x71CE, 0) == PTR_000000);
186+
C(wmemset(PTR_FFFFFF, 0x71CE, 0) == PTR_FFFFFF);
187+
C(wmemset((void*)0x000001, 0x71CE, 0) == (void*)0x000001);
188+
185189
wchar_t data[192 + 1];
186190
memset(data, 0xBC, sizeof(data));
187191
wmemset(wmemset(&data[ 0], 0x0012, 64) + 64, 0x0012, 64);
@@ -194,7 +198,7 @@ int test_wmemset(void) {
194198
test_printf("%p != %p\n", res, &data[64]);
195199
return __LINE__;
196200
}
197-
201+
198202
wchar_t truth[192 + 1];
199203
memset(truth, 0xDE, sizeof(truth));
200204
C(&truth[ 0] == wmemset(&truth[ 0], 0x0012, 64));
@@ -230,7 +234,7 @@ int test_wmemset(void) {
230234
int test_wmemmove(void) {
231235
wchar_t move_str[] =
232236
{0x000F, 0x111F, 0x222F, 0x333F, 0x444F, 0x555F, 0x666F, 0x777F, 0x888F, 0x999F};
233-
const wchar_t truth_str[] =
237+
const wchar_t truth_str[] =
234238
{0x999F, 0x333F, 0x444F, 0x444F, 0x555F, 0x444F, 0x555F, 0x666F, 0x888F, 0x999F};
235239
C(move_str + 5 == wmemmove(move_str + 5, move_str + 4, 3));
236240
C(move_str + 3 == wmemmove(move_str + 3, move_str + 3, 0));

test/standalone/wide_char/src/rename.asm

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,20 @@ _PTR_000000:
99
public _PTR_FFFFFF
1010
_PTR_FFFFFF:
1111
db $FF, $FF, $FF
12+
13+
section .text
14+
15+
public _T_wmemset, _T_wmemcpy, _T_wmemmove, _T_wmemcmp, _T_wmemchr
16+
public _T_wcslen, _T_wcsnlen
17+
18+
_T_wmemset := _wmemset
19+
_T_wmemcpy := _wmemcpy
20+
_T_wmemmove := _wmemmove
21+
_T_wmemcmp := _wmemcmp
22+
_T_wmemchr := _wmemchr
23+
24+
_T_wcslen := _wcslen
25+
_T_wcsnlen := _wcsnlen
26+
27+
extern _wmemset, _wmemcpy, _wmemmove, _wmemcmp, _wmemchr
28+
extern _wcslen, _wcsnlen

0 commit comments

Comments
 (0)