aboutsummaryrefslogtreecommitdiff
path: root/ports
diff options
context:
space:
mode:
authorRoland McGrath <roland@hack.frob.com>2013-03-12 10:03:56 -0700
committerRoland McGrath <roland@hack.frob.com>2013-03-12 17:04:54 -0700
commit4f510e3aeeeb3fd974a12a71789fa9c63ab8c6dd (patch)
tree22a29dd03af4435452d1a3b0993eaecf996c5a81 /ports
parent47c71d9323df1356ac803bdddb7a8f512faf9962 (diff)
downloadglibc-4f510e3aeeeb3fd974a12a71789fa9c63ab8c6dd.zip
glibc-4f510e3aeeeb3fd974a12a71789fa9c63ab8c6dd.tar.gz
glibc-4f510e3aeeeb3fd974a12a71789fa9c63ab8c6dd.tar.bz2
ARM: Make armv6t2 memchr implementation usable without Thumb.
Diffstat (limited to 'ports')
-rw-r--r--ports/ChangeLog.arm3
-rw-r--r--ports/sysdeps/arm/armv6t2/memchr.S25
2 files changed, 26 insertions, 2 deletions
diff --git a/ports/ChangeLog.arm b/ports/ChangeLog.arm
index d24a109..2e250f7 100644
--- a/ports/ChangeLog.arm
+++ b/ports/ChangeLog.arm
@@ -1,5 +1,8 @@
2013-03-12 Roland McGrath <roland@hack.frob.com>
+ * sysdeps/arm/armv6t2/memchr.S [NO_THUMB]:
+ Use .arm rather than .thumb, .thumb_func. Avoid cbz/cnbz instructions.
+
* sysdeps/arm/armv6t2/memchr.S: Change register allocation so ldrd use
is r4,r5 rather than r5,r6; this way ARM mode will allow that ldrd.
diff --git a/ports/sysdeps/arm/armv6t2/memchr.S b/ports/sysdeps/arm/armv6t2/memchr.S
index e253a66..7f644c3 100644
--- a/ports/sysdeps/arm/armv6t2/memchr.S
+++ b/ports/sysdeps/arm/armv6t2/memchr.S
@@ -42,10 +42,12 @@
.syntax unified
.text
+#ifdef NO_THUMB
+ .arm
+#else
.thumb
-
-@ ---------------------------------------------------------------------------
.thumb_func
+#endif
.global memchr
.type memchr,%function
ENTRY(memchr)
@@ -89,14 +91,22 @@ ENTRY(memchr)
15:
ldrd r4,r5, [r0],#8
+#ifndef NO_THUMB
subs r6, r6, #8
+#endif
eor r4,r4, r1 @ Get it so that r4,r5 have 00's where the bytes match the target
eor r5,r5, r1
uadd8 r4, r4, r7 @ Parallel add 0xff - sets the GE bits for anything that wasn't 0
sel r4, r3, r7 @ bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
uadd8 r5, r5, r7 @ Parallel add 0xff - sets the GE bits for anything that wasn't 0
sel r5, r4, r7 @ chained....bytes are 00 for none-00 bytes, or ff for 00 bytes - NOTE INVERSION
+#ifndef NO_THUMB
cbnz r5, 60f
+#else
+ cmp r5, #0
+ bne 60f
+ subs r6, r6, #8
+#endif
bne 15b @ (Flags from the subs above) If not run out of bytes then go around again
pop {r4,r5,r6,r7}
@@ -110,13 +120,24 @@ ENTRY(memchr)
and r2,r2,#7 @ Leave the count remaining as the number after the double words have been done
20:
+#ifndef NO_THUMB
cbz r2, 40f @ 0 length or hit the end already then not found
+#else
+ cmp r2, #0
+ beq 40f
+#endif
21: @ Post aligned section, or just a short call
ldrb r3,[r0],#1
+#ifndef NO_THUMB
subs r2,r2,#1
eor r3,r3,r1 @ r3 = 0 if match - doesn't break flags from sub
cbz r3, 50f
+#else
+ eors r3, r3, r1
+ beq 50f
+ subs r2, r2, #1
+#endif
bne 21b @ on r2 flags
40: