146 lines
2.4 KiB
ArmAsm
146 lines
2.4 KiB
ArmAsm
|
/*
|
||
|
* memcpy routine for Z8000
|
||
|
* Copyright (C) 2004 Christian Groessler <chris@groessler.org>
|
||
|
*
|
||
|
* Permission to use, copy, modify, and distribute this file
|
||
|
* for any purpose is hereby granted without fee, provided that
|
||
|
* the above copyright notice and this notice appears in all
|
||
|
* copies.
|
||
|
*
|
||
|
* This file is distributed WITHOUT ANY WARRANTY; without even the implied
|
||
|
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
*/
|
||
|
|
||
|
/* void *memcpy(void *dest, const void *src, size_t length);
|
||
|
*/
|
||
|
|
||
|
name "memcpy.S"
|
||
|
|
||
|
.text
|
||
|
even
|
||
|
global _memcpy
|
||
|
global memmove_entry
|
||
|
|
||
|
_memcpy:
|
||
|
|
||
|
#ifdef __Z8001__
|
||
|
segm
|
||
|
|
||
|
#ifdef __STD_CALL__
|
||
|
ldl rr6,rr14(#4)
|
||
|
ldl rr4,rr14(#8)
|
||
|
ldl rr2,rr14(#12)
|
||
|
#else
|
||
|
pushl @rr14,rr6
|
||
|
#endif
|
||
|
|
||
|
/* rr2 - length (high word ignored)
|
||
|
* rr4 - src
|
||
|
* rr6 - dest
|
||
|
*/
|
||
|
|
||
|
testl rr2
|
||
|
jr z,finish
|
||
|
|
||
|
memmove_entry: /* external entry point from memmove */
|
||
|
|
||
|
bitb rl7,#0 /* odd destination address? */
|
||
|
jr nz,testsrc
|
||
|
bitb rl5,#0 /* odd source address? */
|
||
|
jr nz,odd_copy
|
||
|
jr t,even_copy /* dest even, src odd */
|
||
|
|
||
|
testsrc:
|
||
|
bitb rl5,#0
|
||
|
jr z,odd_copy /* src even, dest odd */
|
||
|
ldib @rr6,@rr4,r3
|
||
|
jr ov,finish /* jump if r3 is zero now */
|
||
|
|
||
|
/* copy words */
|
||
|
even_copy:
|
||
|
ld r2,r3 /* remember length */
|
||
|
srl r3,#1
|
||
|
jr z,no_words
|
||
|
|
||
|
ldir @rr6,@rr4,r3
|
||
|
|
||
|
no_words:
|
||
|
bitb rl2,#0 /* odd length? */
|
||
|
jr z,finish
|
||
|
ldib @rr6,@rr4,r2 /* yes, copy last byte */
|
||
|
jr finish
|
||
|
|
||
|
/* copy bytes */
|
||
|
odd_copy:
|
||
|
ldirb @rr6,@rr4,r3
|
||
|
|
||
|
finish:
|
||
|
#ifdef __STD_CALL__
|
||
|
ldl rr6,rr14(#4)
|
||
|
#else
|
||
|
popl rr2,@rr14
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#else /* above Z8001, below Z8002 */
|
||
|
|
||
|
|
||
|
unsegm
|
||
|
|
||
|
#ifdef __STD_CALL__
|
||
|
ld r7,r15(#2)
|
||
|
ld r6,r15(#4)
|
||
|
ld r5,r15(#6)
|
||
|
#else
|
||
|
ld r2,r7 /* buffer pointer return value */
|
||
|
#endif
|
||
|
|
||
|
/* r5 - length
|
||
|
* r6 - src
|
||
|
* r7 - dest
|
||
|
*/
|
||
|
test r5
|
||
|
jr z,finish
|
||
|
|
||
|
memmove_entry: /* external entry point from memmove */
|
||
|
|
||
|
bitb rl7,#0 /* odd destination address? */
|
||
|
jr nz,testsrc
|
||
|
bitb rl6,#0 /* odd source address? */
|
||
|
jr nz,odd_copy
|
||
|
jr t,even_copy /* dest even, src odd */
|
||
|
|
||
|
testsrc:
|
||
|
bitb rl6,#0
|
||
|
jr z,odd_copy /* src even, dest odd */
|
||
|
ldib @r7,@r6,r5
|
||
|
jr ov,finish /* jump if r5 is zero now */
|
||
|
|
||
|
/* copy words */
|
||
|
even_copy:
|
||
|
ld r4,r5 /* remember length */
|
||
|
srl r5,#1
|
||
|
jr z,no_words
|
||
|
|
||
|
ldir @r7,@r6,r5
|
||
|
|
||
|
no_words:
|
||
|
bitb rl4,#0 /* odd length? */
|
||
|
jr z,finish
|
||
|
ldib @r7,@r6,r4 /* yes, copy last byte */
|
||
|
jr finish
|
||
|
|
||
|
/* copy bytes */
|
||
|
odd_copy:
|
||
|
ldirb @r7,@r6,r5
|
||
|
|
||
|
finish:
|
||
|
#ifdef __STD_CALL__
|
||
|
ld r7,r15(#2)
|
||
|
#endif
|
||
|
|
||
|
#endif /* Z8002 */
|
||
|
|
||
|
ret
|
||
|
.end
|