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