|
@@ -1,5 +1,5 @@
|
|
|
/* strcmp.S
|
|
/* strcmp.S
|
|
|
- * Copyright (C) 2003, 2005, 2006 Analog Devices Inc., All Rights Reserved.
|
|
|
|
|
|
|
+ * Copyright (C) 2003-2007 Analog Devices Inc., All Rights Reserved.
|
|
|
*
|
|
*
|
|
|
* This file is subject to the terms and conditions of the GNU Library General
|
|
* 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
|
|
* Public License. See the file "COPYING.LIB" in the main directory of this
|
|
@@ -9,6 +9,8 @@
|
|
|
* http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html
|
|
* http://www.analog.com/processors/resources/crosscore/visualDspDevSoftware.html
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
|
|
+#include <sysdep.h>
|
|
|
|
|
+
|
|
|
/* Fast strcmp() for Blackfin.
|
|
/* Fast strcmp() for Blackfin.
|
|
|
* When both strings are aligned, this processes four characters at
|
|
* When both strings are aligned, this processes four characters at
|
|
|
* a time. Uses a hw loop with "very big" count to loop "forever",
|
|
* a time. Uses a hw loop with "very big" count to loop "forever",
|
|
@@ -17,15 +19,11 @@
|
|
|
* loop to check more carefully (same as the unaligned case).
|
|
* loop to check more carefully (same as the unaligned case).
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
-#include <features.h>
|
|
|
|
|
-
|
|
|
|
|
.text
|
|
.text
|
|
|
|
|
|
|
|
.align 2
|
|
.align 2
|
|
|
|
|
|
|
|
-.global _strcmp
|
|
|
|
|
-.type _strcmp, STT_FUNC
|
|
|
|
|
-_strcmp:
|
|
|
|
|
|
|
+ENTRY(_strcmp)
|
|
|
[--sp] = (R7:4);
|
|
[--sp] = (R7:4);
|
|
|
p1 = r0;
|
|
p1 = r0;
|
|
|
p2 = r1;
|
|
p2 = r1;
|
|
@@ -36,13 +34,13 @@ _strcmp:
|
|
|
r0 = r0 | r1; // check both pointers at same time
|
|
r0 = r0 | r1; // check both pointers at same time
|
|
|
r0 <<= 30; // dump all but last 2 bits
|
|
r0 <<= 30; // dump all but last 2 bits
|
|
|
cc = az; // are they zero?
|
|
cc = az; // are they zero?
|
|
|
- if !cc jump unaligned; // no; use unaligned code.
|
|
|
|
|
|
|
+ if !cc jump .Lunaligned; // no; use unaligned code.
|
|
|
// fall-thru for aligned case..
|
|
// fall-thru for aligned case..
|
|
|
|
|
|
|
|
// note that r0 is zero from the previous...
|
|
// note that r0 is zero from the previous...
|
|
|
// p0 set to -1
|
|
// p0 set to -1
|
|
|
|
|
|
|
|
- lsetup (beginloop, endloop) lc0=p0;
|
|
|
|
|
|
|
+ LSETUP (.Lbeginloop, .Lendloop) lc0=p0;
|
|
|
// pick up first words
|
|
// pick up first words
|
|
|
r1 = [p1++];
|
|
r1 = [p1++];
|
|
|
r2 = [p2++];
|
|
r2 = [p2++];
|
|
@@ -51,8 +49,8 @@ _strcmp:
|
|
|
r7.h = 0xFF;
|
|
r7.h = 0xFF;
|
|
|
// loop : 9 cycles to check 4 characters
|
|
// loop : 9 cycles to check 4 characters
|
|
|
cc = r1 == r2;
|
|
cc = r1 == r2;
|
|
|
-beginloop:
|
|
|
|
|
- if !cc jump notequal4; // compare failure, exit loop
|
|
|
|
|
|
|
+.Lbeginloop:
|
|
|
|
|
+ if !cc jump .Lnotequal4; // compare failure, exit loop
|
|
|
|
|
|
|
|
// starting with 44332211
|
|
// starting with 44332211
|
|
|
// see if char 3 or char 1 is 0
|
|
// see if char 3 or char 1 is 0
|
|
@@ -65,18 +63,18 @@ beginloop:
|
|
|
// add to zero, and (r1 is free, reload)
|
|
// add to zero, and (r1 is free, reload)
|
|
|
r6 = r3 +|+ r0 || r1 = [p1++] || nop;
|
|
r6 = r3 +|+ r0 || r1 = [p1++] || nop;
|
|
|
cc |= az; // true if either is zero
|
|
cc |= az; // true if either is zero
|
|
|
- if cc jump zero4; // leave if a zero somewhere
|
|
|
|
|
-endloop:
|
|
|
|
|
|
|
+ if cc jump .Lzero4; // leave if a zero somewhere
|
|
|
|
|
+.Lendloop:
|
|
|
cc = r1 == r2;
|
|
cc = r1 == r2;
|
|
|
|
|
|
|
|
// loop exits
|
|
// loop exits
|
|
|
-notequal4: // compare failure on 4-char compare
|
|
|
|
|
|
|
+.Lnotequal4: // compare failure on 4-char compare
|
|
|
// address pointers are one word ahead;
|
|
// address pointers are one word ahead;
|
|
|
// faster to use zero4 exit code
|
|
// faster to use zero4 exit code
|
|
|
p1 += 4;
|
|
p1 += 4;
|
|
|
p2 += 4;
|
|
p2 += 4;
|
|
|
|
|
|
|
|
-zero4: // one of the bytes in word 1 is zero
|
|
|
|
|
|
|
+.Lzero4: // one of the bytes in word 1 is zero
|
|
|
// but we've already fetched the next word; so
|
|
// but we've already fetched the next word; so
|
|
|
// backup two to look at failing word again
|
|
// backup two to look at failing word again
|
|
|
p1 += -8;
|
|
p1 += -8;
|
|
@@ -87,27 +85,27 @@ zero4: // one of the bytes in word 1 is zero
|
|
|
// here when pointers are unaligned: checks one
|
|
// here when pointers are unaligned: checks one
|
|
|
// character at a time. Also use at the end of
|
|
// character at a time. Also use at the end of
|
|
|
// the word-check algorithm to figure out what happened
|
|
// the word-check algorithm to figure out what happened
|
|
|
-unaligned:
|
|
|
|
|
|
|
+.Lunaligned:
|
|
|
// R0 is non-zero from before.
|
|
// R0 is non-zero from before.
|
|
|
// p0 set to -1
|
|
// p0 set to -1
|
|
|
|
|
|
|
|
r0 = 0 (Z);
|
|
r0 = 0 (Z);
|
|
|
r1 = B[p1++] (Z);
|
|
r1 = B[p1++] (Z);
|
|
|
r2 = B[p2++] (Z);
|
|
r2 = B[p2++] (Z);
|
|
|
- lsetup (beginloop1, endloop1) lc0=p0;
|
|
|
|
|
|
|
+ LSETUP (.Lbeginloop1, .Lendloop1) lc0=p0;
|
|
|
|
|
|
|
|
-beginloop1:
|
|
|
|
|
|
|
+.Lbeginloop1:
|
|
|
cc = r1; // first char must be non-zero
|
|
cc = r1; // first char must be non-zero
|
|
|
// chars must be the same
|
|
// chars must be the same
|
|
|
r3 = r2 - r1 (NS) || r1 = B[p1++] (Z) || nop;
|
|
r3 = r2 - r1 (NS) || r1 = B[p1++] (Z) || nop;
|
|
|
cc &= az;
|
|
cc &= az;
|
|
|
r3 = r0 - r2; // second char must be non-zero
|
|
r3 = r0 - r2; // second char must be non-zero
|
|
|
cc &= an;
|
|
cc &= an;
|
|
|
- if !cc jump exitloop1;
|
|
|
|
|
-endloop1:
|
|
|
|
|
|
|
+ if !cc jump .Lexitloop1;
|
|
|
|
|
+.Lendloop1:
|
|
|
r2 = B[p2++] (Z);
|
|
r2 = B[p2++] (Z);
|
|
|
|
|
|
|
|
-exitloop1: // here means we found a zero or a difference.
|
|
|
|
|
|
|
+.Lexitloop1: // here means we found a zero or a difference.
|
|
|
// we have r2(N), p2(N), r1(N+1), p1(N+2)
|
|
// we have r2(N), p2(N), r1(N+1), p1(N+2)
|
|
|
r1=B[p1+ -2] (Z);
|
|
r1=B[p1+ -2] (Z);
|
|
|
r0 = r1 - r2;
|
|
r0 = r1 - r2;
|