| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 | /* strcmp.S * Copyright (C) 2003-2007 Analog Devices Inc., All Rights Reserved. * * This file is subject to the terms and conditions of the GNU Library General * Public License. See the file "COPYING.LIB" in the main directory of this * archive for more details. * * Non-LGPL License also available as part of VisualDSP++ * http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html */#include <sysdep.h>/* Fast strcmp() for Blackfin. * When both strings are aligned, this processes four characters at * a time. Uses a hw loop with "very big" count to loop "forever", * until difference or a terminating zero is found. * Once the end-case word has been identified, breaks out of the * loop to check more carefully (same as the unaligned case). */.text.align 2.weak _strcmpENTRY(_strcmp)	[--sp] = (R7:4);	p1 = r0;	p2 = r1;	p0 = -1;	/* (need for loop counter init) */	  /* check if byte aligned */	r0 = r0 | r1;	/* check both pointers at same time */	r0 <<= 30;	/* dump all but last 2 bits */	cc = az;	/* are they zero? */	if !cc jump .Lunaligned;	/* no; use unaligned code. */			/* fall-thru for aligned case.. */	  /* note that r0 is zero from the previous... */	  /*           p0 set to -1 */	LSETUP (.Lbeginloop, .Lendloop) lc0=p0;	  /* pick up first words */	r1 = [p1++];	r2 = [p2++];	  /* make up mask:  0FF0FF */	r7 = 0xFF;	r7.h = 0xFF;		/* loop : 9 cycles to check 4 characters */	cc = r1 == r2;.Lbeginloop:	if !cc jump .Lnotequal4;	/* compare failure, exit loop */	  /* starting with   44332211 */	  /* see if char 3 or char 1 is 0 */	r3 = r1 & r7;		/* form 00330011 */	  /* add to zero, and (r2 is free, reload) */	r6 = r3 +|+ r0 || r2 = [p2++] || nop;	cc = az;	/* true if either is zero */	r3 = r1 ^ r3;	        /* form 44002200 (4321^0301 => 4020) */				/* (trick, saves having another mask) */	/* add to zero,  and  (r1 is free, reload) */	r6 = r3 +|+ r0 || r1 = [p1++] || nop;	cc |= az;	/* true if either is zero */	if cc jump .Lzero4;	/* leave if a zero somewhere */.Lendloop:	cc = r1 == r2; /* loop exits */.Lnotequal4:		/* compare failure on 4-char compare */			/* address pointers are one word ahead; */			/* faster to use zero4 exit code */	p1 += 4;	p2 += 4;.Lzero4:			/* one of the bytes in word 1 is zero */			/* but we've already fetched the next word; so */			/* backup two to look at failing word again */	p1 += -8;	p2 += -8;		/* here when pointers are unaligned: checks one */		/* character at a time.  Also use at the end of */		/* the word-check algorithm to figure out what happened */.Lunaligned:	  /*	R0 is non-zero from before. */	  /*           p0 set to -1 */	r0 = 0 (Z);	r1 = B[p1++] (Z);	r2 = B[p2++] (Z);	LSETUP (.Lbeginloop1, .Lendloop1) lc0=p0;.Lbeginloop1:	cc = r1;	/* first char must be non-zero */	/* chars must be the same */	r3 = r2 - r1 (NS) || r1 = B[p1++] (Z) || nop;	cc &= az;	r3 = r0 - r2;	/* second char must be non-zero */	cc &= an;	if !cc jump .Lexitloop1;.Lendloop1:	r2 = B[p2++] (Z);.Lexitloop1: /* here means we found a zero or a difference. */	   /* we have r2(N), p2(N), r1(N+1), p1(N+2) */	r1=B[p1+ -2] (Z);	r0 = r1 - r2;	(r7:4) = [sp++];	rts;.size _strcmp,.-_strcmplibc_hidden_def (strcmp)#ifndef __UCLIBC_HAS_LOCALE__weak_alias (strcmp,strcoll)libc_hidden_def (strcoll)#endif
 |