1
0
mirror of https://github.com/cc65/cc65.git synced 2025-08-08 06:25:17 +00:00

Split memcpy and memmove, since the former is used a lot more often than

the latter.
Optimized the code for smaller size and greater speed.


git-svn-id: svn://svn.cc65.org/cc65/trunk@2382 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz
2003-08-20 10:17:53 +00:00
parent aef8789873
commit 2d168babe9
3 changed files with 114 additions and 89 deletions

View File

@@ -109,6 +109,7 @@ S_OBJS = _cwd.o \
memchr.o \ memchr.o \
memcmp.o \ memcmp.o \
memcpy.o \ memcpy.o \
memmove.o \
memset.o \ memset.o \
modfree.o \ modfree.o \
modload.o \ modload.o \

View File

@@ -1,113 +1,70 @@
; ;
; void* memcpy (void* dest, const void* src, size_t n); ; Ullrich von Bassewitz, 2003-08-20
; void* memmove (void* dest, const void* src, size_t n);
; ;
; Ullrich von Bassewitz, 10.12.1998 ; void* __fastcall__ memcpy (void* dest, const void* src, size_t n);
;
; NOTE: This function contains entry points for memmove, which will ressort
; to memcpy for an upwards copy. Don't change this module without looking
; at memmove!
; ;
.export _memcpy, _memmove .export _memcpy, memcpy_upwards, memcpy_getparams
.import popax .import popax
.importzp ptr1, ptr2, ptr3, tmp1, tmp2 .importzp ptr1, ptr2, ptr3, tmp1
; ---------------------------------------------------------------------- ; ----------------------------------------------------------------------
_memcpy: _memcpy:
jsr getparms ; Get the parameters from stack jsr memcpy_getparams
; Copy upwards memcpy_upwards:
ldy #0
ldx ptr3 ; Get low counter byte
copyup: ldy #0 ; set up to move 256 ; Copy loop
ldx tmp2 ; hi byte of n
beq @L2
@L1: lda (ptr1),y ; get a byte @L1: inx ; Bump low counter byte
sta (ptr2),y ; store it beq @L2 ; Jump on overflow
iny lda (ptr1),y
bne @L1 sta (ptr2),y
inc ptr1+1 ; bump ptrs iny
inc ptr2+1 bne @L1
dex inc ptr1+1 ; Bump pointers
bne @L1 ; do another block inc ptr2+1
bne @L1 ; Branch always
@L2: inc ptr3+1 ; Bump high counter byte
bne @L1
@L2: ldx tmp1 ; get low byte of n ; Done. The low byte of dest is still in ptr2
beq done ; jump if done
@L3: lda (ptr1),y ; get a byte done: lda ptr2
sta (ptr2),y ; store it ldx tmp1 ; get function result (dest)
iny
dex
bne @L3
done: lda ptr3
ldx ptr3+1 ; get function result (dest)
rts rts
; ---------------------------------------------------------------------- ; ----------------------------------------------------------------------
_memmove: ; Get the parameters from stack as follows:
jsr getparms ; Get the parameters from stack ;
; -(size-1) --> ptr3
; src --> ptr1
; dest --> ptr2
; high(dest) --> tmp1
;
; dest is returned in a/x.
cpx ptr1+1 ; dest > src? memcpy_getparams:
bne @L1 eor #$FF
cmp ptr1 sta ptr3
@L1: beq done ; Both pointers are equal - nothing to copy txa
bcc copyup ; Copy upwards eor #$FF
sta ptr3+1 ; Save -(size-1)
; Copy downwards
clc
lda ptr1+1
adc tmp2
sta ptr1+1
clc
lda ptr2+1
adc tmp2
sta ptr2+1
; Copy the incomplete page
ldy tmp1 ; Get low byte of count
beq @L3
@L2: dey
lda (ptr1),y
sta (ptr2),y
tya ; Test Y
bne @L2 ; Jump if not zero
; Copy complete pages
@L3: ldx tmp2 ; Get hi byte of count
beq done
@L4: dec ptr1+1
dec ptr2+1
@L5: dey
lda (ptr1),y
sta (ptr2),y
tya
bne @L5
dex
bne @L4
; Done
beq done
; ----------------------------------------------------------------------
; Get the parameters from stack
getparms:
sta tmp1 ; Save n
stx tmp2
jsr popax ; src jsr popax ; src
sta ptr1 sta ptr1
stx ptr1+1 stx ptr1+1
jsr popax ; dest jsr popax ; dest
sta ptr2 sta ptr2
stx ptr2+1 ; save work copy stx ptr2+1 ; Save work copy
sta ptr3 stx tmp1 ; Save for function result
stx ptr3+1 ; save function result
rts
rts

67
libsrc/common/memmove.s Normal file
View File

@@ -0,0 +1,67 @@
;
; Ullrich von Bassewitz, 2003-08-20
;
; void* __fastcall__ memmove (void* dest, const void* src, size_t size);
;
; NOTE: This function uses entry points from memcpy!
;
.export _memmove
.import memcpy_getparams, memcpy_upwards
.importzp ptr1, ptr2, ptr3, ptr4, tmp1
.macpack generic
.macpack longbranch
; ----------------------------------------------------------------------
_memmove:
sta ptr4
stx ptr4+1 ; Size -> ptr4
jsr memcpy_getparams
; Check for the copy direction. If dest < src, we must copy upwards (start at
; low addresses and increase pointers), otherwise we must copy downwards
; (start at high addresses and decrease pointers).
sec
sbc ptr1
txa
sbc ptr1+1
jcc memcpy_upwards ; Branch if dest < src (upwards copy)
; Copy downwards. Adjust the pointers to the end of the memory regions.
lda ptr1+1
add ptr4+1
sta ptr1+1
lda ptr2+1
add ptr4+1
sta ptr2+1
; Load the low offset into Y, and the counter low byte into X.
ldy ptr4
ldx ptr3
jmp @L2
; Copy loop
@L1: dey
lda (ptr1),y
sta (ptr2),y
@L2: inx ; Bump counter low byte
bne @L1
dec ptr1+1
dec ptr2+1
inc ptr3+1 ; Bump counter high byte
bne @L1
; Done, return dest
done: lda ptr2
ldx tmp1 ; get function result (dest)
rts