1
0
mirror of https://github.com/cc65/cc65.git synced 2025-02-24 09:29:07 +00:00

Optimization of two string functions (size & speed).

This commit is contained in:
IrgendwerA8 2017-02-25 20:19:34 +01:00
parent 97e64c388c
commit 6afcc370ed
3 changed files with 136 additions and 52 deletions

View File

@ -1,5 +1,6 @@
; ;
; Ullrich von Bassewitz, 31.05.1998 ; Ullrich von Bassewitz, 31.05.1998
; Christian Krueger: 2013-Jul-24, minor optimization
; ;
; char* strcat (char* dest, const char* src); ; char* strcat (char* dest, const char* src);
; ;
@ -12,44 +13,35 @@ _strcat:
sta ptr1 ; Save src sta ptr1 ; Save src
stx ptr1+1 stx ptr1+1
jsr popax ; Get dest jsr popax ; Get dest
sta ptr2
stx ptr2+1
sta tmp3 ; Remember for function return sta tmp3 ; Remember for function return
ldy #0 tay
lda #0
sta ptr2 ; access from page start, y contains low byte
stx ptr2+1
; find end of dest findEndOfDest:
lda (ptr2),y
sc1: lda (ptr2),y beq endOfDestFound
beq sc2
iny iny
bne sc1 bne findEndOfDest
inc ptr2+1 inc ptr2+1
bne sc1 bne findEndOfDest
; end found, get offset in y into pointer endOfDestFound:
sty ptr2 ; advance pointer to last y position
ldy #0 ; reset new y-offset
sc2: tya copyByte:
clc lda (ptr1),y
adc ptr2
sta ptr2
bcc sc3
inc ptr2+1
; copy src
sc3: ldy #0
sc4: lda (ptr1),y
sta (ptr2),y sta (ptr2),y
beq sc5 beq done
iny iny
bne sc4 bne copyByte
inc ptr1+1 inc ptr1+1
inc ptr2+1 inc ptr2+1
bne sc4 bne copyByte ; like bra here
; done, return pointer to dest ; return pointer to dest
done: lda tmp3 ; X does still contain high byte
sc5: lda tmp3 ; X does still contain high byte
rts rts

View File

@ -1,5 +1,6 @@
; ;
; Ullrich von Bassewitz, 31.05.1998 ; Ullrich von Bassewitz, 31.05.1998
; Christian Krueger, 2013-Aug-04, minor optimization
; ;
; const char* strchr (const char* s, int c); ; const char* strchr (const char* s, int c);
; ;
@ -9,40 +10,38 @@
.importzp ptr1, tmp1 .importzp ptr1, tmp1
_strchr: _strchr:
sta tmp1 ; Save c sta tmp1 ; Save c
jsr popax ; get s jsr popax ; get s
sta ptr1 tay ; low byte of pointer to y
stx ptr1+1 stx ptr1+1
ldy #0 lda #0
sta ptr1 ; ptr access page wise
Loop: lda (ptr1),y ; Get next char Loop: lda (ptr1),y ; Get next char
beq EOS ; Jump on end of string beq EOS ; Jump on end of string
cmp tmp1 ; Found? cmp tmp1 ; Found?
beq Found ; Jump if yes beq Found ; Jump if yes
iny iny
bne Loop bne Loop
inc ptr1+1 inc ptr1+1
bne Loop ; Branch always bne Loop ; Branch always
; End of string. Check if we're searching for the terminating zero ; End of string. Check if we're searching for the terminating zero
EOS: lda tmp1 ; Get the char we're searching for EOS:
bne NotFound ; Jump if not searching for terminator lda tmp1 ; Get the char we're searching for
bne NotFound ; Jump if not searching for terminator
; Found. Calculate pointer to c. ; Found. Set pointer to c.
Found: ldx ptr1+1 ; Load high byte of pointer Found:
tya ; Low byte offset ldx ptr1+1 ; Load high byte of pointer
clc tya ; low byte is in y
adc ptr1 rts
bcc Found1
inx
Found1: rts
; Not found, return NULL ; Not found, return NULL
NotFound: NotFound:
lda #0 lda #0
tax tax
rts rts

View File

@ -0,0 +1,93 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SourceStringSize 257 // test correct page passing (>256)
static char SourceString[SourceStringSize+1]; // +1 room for terminating null
static char DestinationString[2*SourceStringSize+1]; // will contain two times the source buffer
int main (void)
{
unsigned i,j;
char* p;
/* Print a header */
printf ("strcat(): ");
for (i=0; i < SourceStringSize; ++i)
SourceString[i] = (i%128)+1;
SourceString[i] = 0;
if (strlen(SourceString) != SourceStringSize)
{
printf ("Fail: Source string initialization or 'strlen()' problem!\n");
printf ("Expected length: %u but is %u!\n", SourceStringSize, strlen(SourceString));
exit (EXIT_FAILURE);
}
/* Ensure empty destination string */
DestinationString[0] = 0;
if (strlen(DestinationString) != 0)
{
printf ("Fail: Destination string initialization or 'strlen()' problem!\n");
printf ("Expected length: %u but is %u!\n", 0, strlen(DestinationString));
exit (EXIT_FAILURE);
}
/* Test concatenation to empty buffer */
p = strcat(DestinationString, SourceString);
if (strlen(DestinationString) != SourceStringSize)
{
printf ("Fail: String concatenation to empty buffer!\n");
printf ("Expected length: %u but is %u!\n", SourceStringSize, strlen(DestinationString));
exit (EXIT_FAILURE);
}
/* Test concatenation to non empty buffer */
p = strcat(DestinationString, SourceString);
if (strlen(DestinationString) != 2*SourceStringSize)
{
printf ("Fail: String concatenation to non-empty buffer!\n");
printf ("Expected length: %u but is %u!\n", 2*SourceStringSize, strlen(DestinationString));
exit (EXIT_FAILURE);
}
/* Test return value */
if (p != DestinationString)
{
printf ("Invalid return value!\n");
exit (EXIT_FAILURE);
}
/* Test contents */
for(j=0; j <2; ++j)
for(i=0; i < SourceStringSize; ++i)
{
unsigned position = j*SourceStringSize+i;
unsigned current = DestinationString[position];
unsigned expected = (i%128)+1;
if (current != expected)
{
printf ("Fail: Unexpected destination buffer contents at position %u!\n", position);
printf ("Expected %u, but is %u!\n", expected, current);
exit (EXIT_FAILURE);
}
}
/* Test passed */
printf ("Passed\n");
return EXIT_SUCCESS;
}