[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit
Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/build/uClibc/libc/string/bfin/strcmp.S b/ap/build/uClibc/libc/string/bfin/strcmp.S
new file mode 100644
index 0000000..ef23aa9
--- /dev/null
+++ b/ap/build/uClibc/libc/string/bfin/strcmp.S
@@ -0,0 +1,122 @@
+/* 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 _strcmp
+ENTRY(_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,.-_strcmp
+
+libc_hidden_def (strcmp)
+
+#ifndef __UCLIBC_HAS_LOCALE__
+weak_alias (strcmp,strcoll)
+libc_hidden_def (strcoll)
+#endif