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 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
|
/*
* memcmp 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.
*/
/* int memcmp(const void *b1, const void *b2, size_t length);
*/
name "memcmp.S"
.text
even
global _memcmp
_memcmp:
#ifdef __Z8001__
segm
#ifdef __STD_CALL__
ldl rr6,rr14(#4)
ldl rr4,rr14(#8)
ldl rr2,rr14(#12)
#endif
/* rr2 - length (high word ignored)
* rr4 - b2
* rr6 - b1
*/
clr r1 /* initialize return value */
testl rr2
jr z,finish
bitb rl7,#0 /* odd b1? */
jr nz,testb2
bitb rl5,#0 /* odd b2? */
jr nz,odd_cmp /* b1 even, b2 odd */
jr t,even_cmp
testb2:
bitb rl5,#0
jr z,odd_cmp /* b2 even, b1 odd */
cpsib @rr6,@rr4,r3,eq
jr z,beq /* bytes are the same */
jr t,byte_diff
beq: jr ov,finish /* jump if r3 is zero now */
/* compare words */
even_cmp:
ld r2,r3 /* remember length */
srl r3,#1
jr z,no_words
cpsir @rr6,@rr4,r3,ne
jr nz,no_words
dec r7,#2
dec r5,#2 /* point to different bytes */
ldk r3,#2
jr t,odd_cmp
no_words:
bitb rl2,#0 /* odd length? */
jr z,finish
cpsib @rr6,@rr4,r3,eq
jr z,finish /* last bytes are the same */
jr t,byte_diff
/* compare bytes */
odd_cmp:
cpsirb @rr6,@rr4,r3,ne
jr nz,finish
byte_diff:
dec r7,#1
dec r5,#1 /* point to different bytes */
ldb rl1,@rr6
clr r0
ldb rl0,@rr4
sub r1,r0
finish: /* set return value */
#ifdef __STD_CALL__
ld r7,r1
#else
ld r2,r1
#endif
#else /* above Z8001, below Z8002 */
unsegm
#ifdef __STD_CALL__
ld r7,r15(#2)
ld r6,r15(#4)
ld r5,r15(#6)
#endif
/* r5 - length
* r6 - b2
* r7 - b1
*/
clr r1 /* initialize return value */
test r5
jr z,finish
bitb rl7,#0 /* odd destination address? */
jr nz,testb2
bitb rl6,#0 /* odd source address? */
jr nz,odd_cmp /* b1 even, b2 odd */
jr t,even_cmp
testb2:
bitb rl6,#0
jr z,odd_cmp /* b2 even, b1 odd */
cpsib @r7,@r6,r5,eq
jr z,beq /* bytes are the same */
jr t,byte_diff
beq: jr ov,finish /* jump if r3 is zero now */
/* compare words */
even_cmp:
ld r4,r5 /* remember length */
srl r5,#1
jr z,no_words
cpsir @r7,@r6,r5,ne
jr nz,no_words
dec r7,#2
dec r6,#2 /* point to different bytes */
ldk r5,#2
jr t,odd_cmp
no_words:
bitb rl4,#0 /* odd length? */
jr z,finish
cpsib @r7,@r6,r4,eq
jr z,finish /* last bytes are the same */
jr t,byte_diff
/* compare bytes */
odd_cmp:
cpsirb @r7,@r6,r5,ne
jr nz,finish
byte_diff:
dec r7,#1
dec r6,#1 /* point to different bytes */
ldb rl1,@r7
clr r0
ldb rl0,@r6
sub r1,r0
finish:
#ifdef __STD_CALL__
ld r7,r1
#else
ld r2,r1
#endif
#endif /* Z8002 */
ret
.end
|