From 55d3a6ea39c3275958d2ac9a666b7bf8ffeb6ed7 Mon Sep 17 00:00:00 2001 From: Colin Leroy-Mira Date: Wed, 4 Sep 2024 22:52:52 +0200 Subject: [PATCH] Optimize stpcpy's size and speed --- libsrc/common/stpcpy.c | 7 ------- libsrc/common/stpcpy.s | 22 ++++++++++++++++++++++ libsrc/common/strcpy.s | 7 +++++-- test/val/stpcpy.c | 13 +++++++++++-- 4 files changed, 38 insertions(+), 11 deletions(-) delete mode 100644 libsrc/common/stpcpy.c create mode 100644 libsrc/common/stpcpy.s diff --git a/libsrc/common/stpcpy.c b/libsrc/common/stpcpy.c deleted file mode 100644 index 12af47f2f3..0000000000 --- a/libsrc/common/stpcpy.c +++ /dev/null @@ -1,7 +0,0 @@ -#include - -char * __fastcall__ stpcpy (char * dst, const char * src) -{ - strcpy (dst, src); - return dst + strlen (src); -} diff --git a/libsrc/common/stpcpy.s b/libsrc/common/stpcpy.s new file mode 100644 index 0000000000..c8a10db947 --- /dev/null +++ b/libsrc/common/stpcpy.s @@ -0,0 +1,22 @@ +; +; Colin Leroy-Mira, 4 Sept. 2024 +; +; char* stpcpy (char* dest, const char* src); +; + + .export _stpcpy + .import _strcpy + + .importzp tmp1, ptr2 + +_stpcpy: + jsr _strcpy + + ldx ptr2+1 ; Load dest pointer's last high byte + tya ; Get the last offset strcpy wrote to + + clc + adc ptr2 ; Add to low byte value + bcc :+ + inx +: rts ; Return pointer to dest's terminator diff --git a/libsrc/common/strcpy.s b/libsrc/common/strcpy.s index 77b39fe761..9a100f5408 100644 --- a/libsrc/common/strcpy.s +++ b/libsrc/common/strcpy.s @@ -25,6 +25,9 @@ L1: lda (ptr1),y inc ptr2+1 bne L1 -L9: lda ptr2 ; X still contains high byte - rts +L9: lda ptr2 ; X still contains dest's original high byte + ; On exit, we want AX to be dest (as this is what strcpy returns). + ; We also want (ptr2),y to still point to dest's terminator, as this + ; is used by stpcpy(). + rts diff --git a/test/val/stpcpy.c b/test/val/stpcpy.c index 8bdbfb9263..1cc6458edf 100644 --- a/test/val/stpcpy.c +++ b/test/val/stpcpy.c @@ -8,10 +8,12 @@ #define STR_SHORT "Hello, World!" #define STR_LONG "This is a longer test string for stpcpy." +char dest[512]; +char multi_page[300]; + int main () { - char dest[50]; const char *src_empty; const char *src_short; const char *src_long; @@ -38,7 +40,14 @@ main () assert(end == &dest[sizeof (STR_LONG) - 1]); printf ("Test 3 passed.\n"); + memset(multi_page, 'a', sizeof(multi_page)-1); + multi_page[sizeof(multi_page)-1] = '\0'; + end = stpcpy (dest, multi_page); + assert(!strcmp (dest, multi_page)); + assert(!*end); + assert(end == &dest[sizeof (multi_page) - 1]); + printf ("Test 4 passed.\n"); + printf ("All tests passed.\n"); return EXIT_SUCCESS; } -