1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
/*
* 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
|