Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions src/libc/memmove.src
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
assume adl=1

section .text

public _memmove

if PREFER_OS_LIBC

_memmove := 0000A8h

else

if 1

; Optimized for when src != dst
_memmove:
; src > dst | LDIR | 32F + 15R + 1
; src < dst | LDDR | 35F + 12R + 2
; src = dst | LDDR | 35F + 12R + 2
; zero size | | 24F + 12R + 2

ld iy, -1
add iy, sp
ld bc, (iy + 10)
sbc hl, hl
add hl, bc
jr nc, .zero
ld hl, (iy + 7)
ld de, (iy + 4)
sbc hl, de
; src <= dst
jr c, .copy_backwards
; src > dst
; .copy_forwards:
add hl, de
inc hl
ldir
.zero:
ld hl, (iy + 4)
ret

.copy_backwards:
; move HL and DE to the end
ex de, hl
add hl, bc
ex de, hl ; HL = src - dst - 1, DE = dst + size
add hl, de ; HL = src + size - 1
dec de ; DE = dst + size - 1
lddr
ex de, hl
inc hl
ret

else

; Optimized for when src == dst
_memmove:
; src > dst | LDIR | 33F + 15R + 2
; src < dst | LDDR | 36F + 12R + 2
; src = dst | | 29F + 12R + 2
; zero size | | 24F + 12R + 2

ld iy, -1
add iy, sp
ld bc, (iy + 10)
sbc hl, hl
add hl, bc
jr nc, .zero
ld de, (iy + 4)
ld hl, (iy + 7)
or a, a
sbc hl, de
; src < dst
jr c, .copy_backwards
; src >= dst
; .copy_forwards:
add hl, de
; src == dst
ret z ; skips LDIR when src == dst
; src > dst
ldir
.zero:
ld hl, (iy + 4)
ret

.copy_backwards:
; move HL and DE to the end
dec de ; DE = dst - 1
ex de, hl
add hl, bc ; HL = dst + size - 1, DE = src - dst
ex de, hl
add hl, de ; HL = src + size - 1, DE = dst + size - 1
lddr
ex de, hl
inc hl
ret

end if

end if
2 changes: 0 additions & 2 deletions src/libc/os.src
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ _longjmp := 000098h
_memchr := 00009Ch
public _memcmp
_memcmp := 0000A0h
public _memmove
_memmove := 0000A8h
public _setjmp
_setjmp := 0000B8h
public _strcat
Expand Down
28 changes: 27 additions & 1 deletion test/standalone/asprintf_fprintf/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ extern void* NULL_ptr;
void *T_memcpy(void *__restrict dest, const void *__restrict src, size_t n)
__attribute__((nonnull(1, 2)));

void *T_memmove(void *dest, const void *src, size_t n)
__attribute__((nonnull(1, 2)));

void *T_memset(void *s, int c, size_t n)
__attribute__((nonnull(1)));

Expand Down Expand Up @@ -65,6 +68,7 @@ void T_bzero(void* s, size_t n);
#else

#define T_memcpy memcpy
#define T_memmove memmove
#define T_memset memset
#define T_memcmp memcmp
#define T_memccpy memccpy
Expand Down Expand Up @@ -575,6 +579,24 @@ int memrchr_test(void) {
return 0;
}

int memmove_test(void) {
char move_str[] = "0123456789";
const char truth_str[] = "9344545689";
C(move_str + 5 == (char*)T_memmove(move_str + 5, move_str + 4, 3));
C(move_str + 3 == (char*)T_memmove(move_str + 3, move_str + 3, 0));
C(move_str + 1 == (char*)T_memmove(move_str + 1, move_str + 3, 4));
C(move_str + 2 == (char*)T_memmove(move_str + 2, move_str + 2, 6));
C(move_str + 9 == (char*)T_memmove(move_str + 9, move_str + 0, 0));
C(move_str + 0 == (char*)T_memmove(move_str + 0, move_str + 9, 1));
C(strcmp(move_str, truth_str) == 0);

C(NULL_ptr - 0 == (char*)T_memmove(NULL_ptr - 0, NULL_ptr - 0, 0));
C(NULL_ptr - 0 == (char*)T_memmove(NULL_ptr - 0, NULL_ptr - 1, 0));
C(NULL_ptr - 1 == (char*)T_memmove(NULL_ptr - 1, NULL_ptr - 0, 0));

return 0;
}

int run_tests(void) {
int ret = 0;
/* boot_asprintf */
Expand Down Expand Up @@ -608,10 +630,14 @@ int run_tests(void) {
ret = strncmp_test();
if (ret != 0) { return ret; }

/* strncmp */
/* memrchr */
ret = memrchr_test();
if (ret != 0) { return ret; }

/* memrchr */
ret = memmove_test();
if (ret != 0) { return ret; }

return 0;
}

Expand Down
5 changes: 3 additions & 2 deletions test/standalone/asprintf_fprintf/src/rename.asm
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

section .text

public _T_memset, _T_memcpy, _T_memcmp, _T_memccpy, _T_mempcpy, _T_memrchr
public _T_memset, _T_memcpy, _T_memmove, _T_memcmp, _T_memccpy, _T_mempcpy, _T_memrchr
public _T_strlen, _T_strcmp, _T_strncmp, _T_stpcpy
public _T_bzero

_T_memset := _memset
_T_memcpy := _memcpy
_T_memmove := _memmove
_T_memcmp := _memcmp
_T_memccpy := _memccpy
_T_mempcpy := _mempcpy
Expand All @@ -26,6 +27,6 @@ _T_bzero := _bzero
_NULL_ptr:
db $00, $00, $00

extern _memset, _memcpy, _memcmp, _memccpy, _mempcpy, _memrchr
extern _memset, _memcpy, _memmove, _memcmp, _memccpy, _mempcpy, _memrchr
extern _strlen, _strcmp, _strncmp, _stpcpy
extern _bzero
Loading