Skip to content

Commit f0f8c15

Browse files
calc84maniacmateoconlechuga
authored andcommitted
Optimize strlcpy more
1 parent 9baa79f commit f0f8c15

File tree

1 file changed

+24
-40
lines changed

1 file changed

+24
-40
lines changed

src/libc/strlcpy.src

Lines changed: 24 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -10,76 +10,60 @@
1010
_strlcpy:
1111

1212
ld iy, 0
13+
lea bc, iy ; set bc to 0
1314
add iy, sp
1415

1516
; do min(strlen(src), dsize-1)
1617

1718
; strlen(src)
1819
ld hl, (iy + 6) ; hl = pointer to src
19-
xor a,a ; clear carry and set a to 0
20-
ld bc, 0
20+
xor a, a ; clear carry and set a to 0
2121
cpir ; dec bc until byte at (hl) matches a (= NUL)
2222
; calculate HL=-BC-1
23-
sbc hl,hl
23+
sbc hl, hl
2424
scf
25-
sbc hl,bc
25+
sbc hl, bc ; always sets carry flag
2626
; now hl = strlen(src)
2727

2828
push hl ; save this for after dsize check
2929

3030
ld bc, (iy + 9) ; bc = dsize
31+
ex de, hl ; de = strlen(src)
3132

3233
; check if dsize is zero
33-
xor a,a ; clear carry and set a to 0
34-
sbc hl, hl
35-
sbc hl, bc
36-
jr z, .strlcpy_done ; do nothing if dsize is zero
34+
sbc hl, hl ; set hl to -1, carry was already set
35+
add hl, bc ; hl = -1 + dsize
36+
jr nc, .strlcpy_done ; do nothing if dsize is zero
3737

38-
dec bc ; bc = dsize - 1
38+
; dsize is not zero, compare them
39+
; hl = dsize - 1
40+
; de = strlen(src)
3941

40-
; restore hl without changing the stack
41-
pop hl ; get it back
42-
push hl ; save it for the end
42+
; carry flag is set, so calculate hl - (de + 1)
43+
sbc hl, de
4344

44-
; dsize is not zero, compare them
45-
; hl = strlen(src)
46-
; bc = dsize - 1
47-
48-
; https://www.msx.org/forum/development/msx-development/how-compare-16bits-registers-z80
49-
or a ; clear carry flag
50-
sbc hl, bc
51-
add hl, bc
52-
53-
; if hl >= bc, c = 0; keep bc as is
54-
; if strlen(src) >= (dsize - 1), c = 0; keep bc as is
55-
jr nc, .ready_for_ldir
56-
57-
; hl < bc, so strlen(src) < (dsize - 1); set bc to the value in hl
58-
push hl
45+
; if hl <= de, (dsize - 1) <= strlen(src); keep bc as dsize
46+
jr c, .ready_for_ldir
47+
48+
; hl > de, so (dsize - 1) > strlen(src); set bc to strlen(src) + 1
49+
push de
5950
pop bc
51+
inc bc
6052

6153
.ready_for_ldir:
6254
ld de, (iy + 3) ; put dst in de
63-
64-
; check if bc is zero
65-
xor a,a ; clear carry and set a to 0
66-
sbc hl, hl
67-
sbc hl, bc
68-
jr z, .null_terminate ; null terminate if bc is zero
69-
7055
ld hl, (iy + 6) ; put src in hl
71-
; bc is filled already
56+
; bc is filled already and greater than 0
7257

7358
; at this point we are set up for an ldir:
7459
; hl has the start address
7560
; de has the destination address
76-
; bc has the length
77-
61+
; bc has the length (including space for null terminator)
7862
ldir
7963

80-
.null_terminate:
81-
; dsize is nonzero, null terminate dst
82-
xor a,a ; clear carry and set a to 0 (= NUL)
64+
; replace final byte with NUL, in case src null terminator wasn't reached
65+
dec de
66+
; a is already 0
8367
ld (de), a ; store null terminator at the address pointed to by de
8468

8569
.strlcpy_done:

0 commit comments

Comments
 (0)