memcmp.S revision 137464
1194701Srpaulo/* $NetBSD: memcmp.S,v 1.3 2003/10/14 07:51:45 scw Exp $ */ 2194701Srpaulo 3194701Srpaulo/* 4194701Srpaulo * Copyright 2003 Wasabi Systems, Inc. 5194701Srpaulo * All rights reserved. 6194701Srpaulo * 7194701Srpaulo * Written by Steve C. Woodford for Wasabi Systems, Inc. 8194701Srpaulo * 9194701Srpaulo * Redistribution and use in source and binary forms, with or without 10194701Srpaulo * modification, are permitted provided that the following conditions 11194701Srpaulo * are met: 12194701Srpaulo * 1. Redistributions of source code must retain the above copyright 13194701Srpaulo * notice, this list of conditions and the following disclaimer. 14194701Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 15194701Srpaulo * notice, this list of conditions and the following disclaimer in the 16194701Srpaulo * documentation and/or other materials provided with the distribution. 17194701Srpaulo * 3. All advertising materials mentioning features or use of this software 18194701Srpaulo * must display the following acknowledgement: 19194701Srpaulo * This product includes software developed for the NetBSD Project by 20194701Srpaulo * Wasabi Systems, Inc. 21194701Srpaulo * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22194701Srpaulo * or promote products derived from this software without specific prior 23194701Srpaulo * written permission. 24194701Srpaulo * 25194701Srpaulo * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26194701Srpaulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27194701Srpaulo * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28194701Srpaulo * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29194701Srpaulo * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30194701Srpaulo * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31194701Srpaulo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32194701Srpaulo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33194701Srpaulo * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34194701Srpaulo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35194701Srpaulo * POSSIBILITY OF SUCH DAMAGE. 36194701Srpaulo */ 37194701Srpaulo/* 38194701Srpaulo * Copyright (c) 2002 ARM Ltd 39194701Srpaulo * All rights reserved. 40194701Srpaulo * 41194701Srpaulo * Redistribution and use in source and binary forms, with or without 42194701Srpaulo * modification, are permitted provided that the following conditions 43194701Srpaulo * are met: 44194701Srpaulo * 1. Redistributions of source code must retain the above copyright 45194701Srpaulo * notice, this list of conditions and the following disclaimer. 46194701Srpaulo * 2. Redistributions in binary form must reproduce the above copyright 47194701Srpaulo * notice, this list of conditions and the following disclaimer in the 48194701Srpaulo * documentation and/or other materials provided with the distribution. 49195185Srpaulo * 3. The name of the company may not be used to endorse or promote 50194701Srpaulo * products derived from this software without specific prior written 51194701Srpaulo * permission. 52194701Srpaulo * 53194701Srpaulo * THIS SOFTWARE IS PROVIDED BY ARM LTD ``AS IS'' AND ANY EXPRESS OR IMPLIED 54194701Srpaulo * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 55194701Srpaulo * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 56194701Srpaulo * IN NO EVENT SHALL ARM LTD BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 57194701Srpaulo * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 58194701Srpaulo * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 59194701Srpaulo * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 60194701Srpaulo * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 61194701Srpaulo * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 62194701Srpaulo * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 63194701Srpaulo */ 64194701Srpaulo 65194701Srpaulo#include <machine/asm.h> 66194701Srpaulo 67194701Srpaulo__FBSDID("$FreeBSD: head/lib/libc/arm/string/memcmp.S 137464 2004-11-09 16:49:14Z cognet $"); 68194701Srpaulo 69194701SrpauloENTRY(memcmp) 70194701Srpaulo mov ip, r0 71194701Srpaulo#if defined(_KERNEL) && !defined(_STANDALONE) 72194701Srpaulo cmp r2, #0x06 73194701Srpaulo beq .Lmemcmp_6bytes 74194701Srpaulo#endif 75194701Srpaulo mov r0, #0x00 76194701Srpaulo 77194701Srpaulo /* Are both addresses aligned the same way? */ 78194701Srpaulo cmp r2, #0x00 79194701Srpaulo eornes r3, ip, r1 80194701Srpaulo RETeq /* len == 0, or same addresses! */ 81194701Srpaulo tst r3, #0x03 82194701Srpaulo subne r2, r2, #0x01 83194701Srpaulo bne .Lmemcmp_bytewise2 /* Badly aligned. Do it the slow way */ 84194701Srpaulo 85194701Srpaulo /* Word-align the addresses, if necessary */ 86194701Srpaulo sub r3, r1, #0x05 87194701Srpaulo ands r3, r3, #0x03 88194701Srpaulo add r3, r3, r3, lsl #1 89194701Srpaulo addne pc, pc, r3, lsl #3 90194701Srpaulo nop 91194701Srpaulo 92194701Srpaulo /* Compare up to 3 bytes */ 93194701Srpaulo ldrb r0, [ip], #0x01 94194701Srpaulo ldrb r3, [r1], #0x01 95194701Srpaulo subs r0, r0, r3 96194701Srpaulo RETne 97194701Srpaulo subs r2, r2, #0x01 98194701Srpaulo RETeq 99194701Srpaulo 100194701Srpaulo /* Compare up to 2 bytes */ 101194701Srpaulo ldrb r0, [ip], #0x01 102194701Srpaulo ldrb r3, [r1], #0x01 103194701Srpaulo subs r0, r0, r3 104194701Srpaulo RETne 105194701Srpaulo subs r2, r2, #0x01 106194701Srpaulo RETeq 107194701Srpaulo 108194701Srpaulo /* Compare 1 byte */ 109194701Srpaulo ldrb r0, [ip], #0x01 110194701Srpaulo ldrb r3, [r1], #0x01 111194701Srpaulo subs r0, r0, r3 112194701Srpaulo RETne 113194701Srpaulo subs r2, r2, #0x01 114194701Srpaulo RETeq 115194701Srpaulo 116194701Srpaulo /* Compare 4 bytes at a time, if possible */ 117194701Srpaulo subs r2, r2, #0x04 118194701Srpaulo bcc .Lmemcmp_bytewise 119194701Srpaulo.Lmemcmp_word_aligned: 120194701Srpaulo ldr r0, [ip], #0x04 121194701Srpaulo ldr r3, [r1], #0x04 122194701Srpaulo subs r2, r2, #0x04 123194701Srpaulo cmpcs r0, r3 124194701Srpaulo beq .Lmemcmp_word_aligned 125194701Srpaulo sub r0, r0, r3 126194701Srpaulo 127194701Srpaulo /* Correct for extra subtraction, and check if done */ 128194701Srpaulo adds r2, r2, #0x04 129194701Srpaulo cmpeq r0, #0x00 /* If done, did all bytes match? */ 130194701Srpaulo RETeq /* Yup. Just return */ 131194701Srpaulo 132194701Srpaulo /* Re-do the final word byte-wise */ 133194701Srpaulo sub ip, ip, #0x04 134194701Srpaulo sub r1, r1, #0x04 135194701Srpaulo 136194701Srpaulo.Lmemcmp_bytewise: 137194701Srpaulo add r2, r2, #0x03 138194701Srpaulo.Lmemcmp_bytewise2: 139194701Srpaulo ldrb r0, [ip], #0x01 140194701Srpaulo ldrb r3, [r1], #0x01 141194701Srpaulo subs r2, r2, #0x01 142194701Srpaulo cmpcs r0, r3 143194701Srpaulo beq .Lmemcmp_bytewise2 144194701Srpaulo sub r0, r0, r3 145194701Srpaulo RET 146 147#if defined(_KERNEL) && !defined(_STANDALONE) 148 /* 149 * 6 byte compares are very common, thanks to the network stack. 150 * This code is hand-scheduled to reduce the number of stalls for 151 * load results. Everything else being equal, this will be ~32% 152 * faster than a byte-wise memcmp. 153 */ 154 .align 5 155.Lmemcmp_6bytes: 156 ldrb r3, [r1, #0x00] /* r3 = b2#0 */ 157 ldrb r0, [ip, #0x00] /* r0 = b1#0 */ 158 ldrb r2, [r1, #0x01] /* r2 = b2#1 */ 159 subs r0, r0, r3 /* r0 = b1#0 - b2#0 */ 160 ldreqb r3, [ip, #0x01] /* r3 = b1#1 */ 161 RETne /* Return if mismatch on #0 */ 162 subs r0, r3, r2 /* r0 = b1#1 - b2#1 */ 163 ldreqb r3, [r1, #0x02] /* r3 = b2#2 */ 164 ldreqb r0, [ip, #0x02] /* r0 = b1#2 */ 165 RETne /* Return if mismatch on #1 */ 166 ldrb r2, [r1, #0x03] /* r2 = b2#3 */ 167 subs r0, r0, r3 /* r0 = b1#2 - b2#2 */ 168 ldreqb r3, [ip, #0x03] /* r3 = b1#3 */ 169 RETne /* Return if mismatch on #2 */ 170 subs r0, r3, r2 /* r0 = b1#3 - b2#3 */ 171 ldreqb r3, [r1, #0x04] /* r3 = b2#4 */ 172 ldreqb r0, [ip, #0x04] /* r0 = b1#4 */ 173 RETne /* Return if mismatch on #3 */ 174 ldrb r2, [r1, #0x05] /* r2 = b2#5 */ 175 subs r0, r0, r3 /* r0 = b1#4 - b2#4 */ 176 ldreqb r3, [ip, #0x05] /* r3 = b1#5 */ 177 RETne /* Return if mismatch on #4 */ 178 sub r0, r3, r2 /* r0 = b1#5 - b2#5 */ 179 RET 180#endif 181