1/* 2 * memcmp routine for Z8000 3 * Copyright (C) 2004 Christian Groessler <chris@groessler.org> 4 * 5 * Permission to use, copy, modify, and distribute this file 6 * for any purpose is hereby granted without fee, provided that 7 * the above copyright notice and this notice appears in all 8 * copies. 9 * 10 * This file is distributed WITHOUT ANY WARRANTY; without even the implied 11 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 */ 13 14/* int memcmp(const void *b1, const void *b2, size_t length); 15 */ 16 17 name "memcmp.S" 18 19 .text 20 even 21global _memcmp 22 23_memcmp: 24 25#ifdef __Z8001__ 26 segm 27 28#ifdef __STD_CALL__ 29 ldl rr6,rr14(#4) 30 ldl rr4,rr14(#8) 31 ldl rr2,rr14(#12) 32#endif 33 34/* rr2 - length (high word ignored) 35 * rr4 - b2 36 * rr6 - b1 37 */ 38 39 clr r1 /* initialize return value */ 40 testl rr2 41 jr z,finish 42 43 bitb rl7,#0 /* odd b1? */ 44 jr nz,testb2 45 bitb rl5,#0 /* odd b2? */ 46 jr nz,odd_cmp /* b1 even, b2 odd */ 47 jr t,even_cmp 48 49testb2: 50 bitb rl5,#0 51 jr z,odd_cmp /* b2 even, b1 odd */ 52 53 cpsib @rr6,@rr4,r3,eq 54 jr z,beq /* bytes are the same */ 55 jr t,byte_diff 56 57beq: jr ov,finish /* jump if r3 is zero now */ 58 59/* compare words */ 60even_cmp: 61 ld r2,r3 /* remember length */ 62 srl r3,#1 63 jr z,no_words 64 65 cpsir @rr6,@rr4,r3,ne 66 jr nz,no_words 67 68 dec r7,#2 69 dec r5,#2 /* point to different bytes */ 70 ldk r3,#2 71 jr t,odd_cmp 72 73no_words: 74 bitb rl2,#0 /* odd length? */ 75 jr z,finish 76 77 cpsib @rr6,@rr4,r3,eq 78 jr z,finish /* last bytes are the same */ 79 jr t,byte_diff 80 81/* compare bytes */ 82odd_cmp: 83 cpsirb @rr6,@rr4,r3,ne 84 jr nz,finish 85 86byte_diff: 87 dec r7,#1 88 dec r5,#1 /* point to different bytes */ 89 90 ldb rl1,@rr6 91 clr r0 92 ldb rl0,@rr4 93 sub r1,r0 94 95finish: /* set return value */ 96#ifdef __STD_CALL__ 97 ld r7,r1 98#else 99 ld r2,r1 100#endif 101 102 103#else /* above Z8001, below Z8002 */ 104 105 106 unsegm 107 108#ifdef __STD_CALL__ 109 ld r7,r15(#2) 110 ld r6,r15(#4) 111 ld r5,r15(#6) 112#endif 113 114/* r5 - length 115 * r6 - b2 116 * r7 - b1 117 */ 118 119 clr r1 /* initialize return value */ 120 test r5 121 jr z,finish 122 123 bitb rl7,#0 /* odd destination address? */ 124 jr nz,testb2 125 bitb rl6,#0 /* odd source address? */ 126 jr nz,odd_cmp /* b1 even, b2 odd */ 127 jr t,even_cmp 128 129testb2: 130 bitb rl6,#0 131 jr z,odd_cmp /* b2 even, b1 odd */ 132 133 cpsib @r7,@r6,r5,eq 134 jr z,beq /* bytes are the same */ 135 jr t,byte_diff 136 137beq: jr ov,finish /* jump if r3 is zero now */ 138 139/* compare words */ 140even_cmp: 141 ld r4,r5 /* remember length */ 142 srl r5,#1 143 jr z,no_words 144 145 cpsir @r7,@r6,r5,ne 146 jr nz,no_words 147 148 dec r7,#2 149 dec r6,#2 /* point to different bytes */ 150 ldk r5,#2 151 jr t,odd_cmp 152 153no_words: 154 bitb rl4,#0 /* odd length? */ 155 jr z,finish 156 157 cpsib @r7,@r6,r4,eq 158 jr z,finish /* last bytes are the same */ 159 jr t,byte_diff 160 161/* compare bytes */ 162odd_cmp: 163 cpsirb @r7,@r6,r5,ne 164 jr nz,finish 165 166byte_diff: 167 dec r7,#1 168 dec r6,#1 /* point to different bytes */ 169 170 ldb rl1,@r7 171 clr r0 172 ldb rl0,@r6 173 sub r1,r0 174 175finish: 176#ifdef __STD_CALL__ 177 ld r7,r1 178#else 179 ld r2,r1 180#endif 181 182#endif /* Z8002 */ 183 184 ret 185 .end 186