Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2009-03-16 23:12:30 +0300
committerJeff Johnston <jjohnstn@redhat.com>2009-03-16 23:12:30 +0300
commitd70118655b0d30849c5a85e2afbb72b91e395a63 (patch)
treefba90704b6bcbd7c14def7c3b1d105a49c9ed564 /newlib/libc/machine
parent8213c3f8e3e8e9276e27d6920ff2008ed234e4a3 (diff)
2009-03-16 Mark Mitchell <mark@codesourcery.com>
* libc/machine/arm/strlen.c (strlen): Fix defect in Thumb-2 mode. 2009-03-16 Richard Earnshaw <rearnsha@arm.com> * libc/machine/arm/strlen.c (strlen): Correctly detect end-of-string. * libc/machine/arm/strcpy.c (strcpy): Likewise. * libc/machine/arm/strcmp.c (strcmp, strcmp_unaligned): Likewise.
Diffstat (limited to 'newlib/libc/machine')
-rw-r--r--newlib/libc/machine/arm/strcmp.c12
-rw-r--r--newlib/libc/machine/arm/strcpy.c6
-rw-r--r--newlib/libc/machine/arm/strlen.c19
3 files changed, 20 insertions, 17 deletions
diff --git a/newlib/libc/machine/arm/strcmp.c b/newlib/libc/machine/arm/strcmp.c
index f7d39aa77..6b3347598 100644
--- a/newlib/libc/machine/arm/strcmp.c
+++ b/newlib/libc/machine/arm/strcmp.c
@@ -97,7 +97,7 @@ __attribute__((naked)) strcmp (const char* s1, const char* s2)
"cmp ip, r3\n\t"
"itttt eq\n\t"
/* check for any zero bytes in first word */
- "eoreq r2, r2, ip\n\t"
+ "biceq r2, r2, ip\n\t"
"tsteq r2, "magic2(r4)"\n\t"
"ldreq ip, [r0], #4\n\t"
"ldreq r3, [r1], #4\n\t"
@@ -171,9 +171,9 @@ strcmp_unaligned(const char* s1, const char* s2)
w2 RSHIFT= shift; \
break; \
} \
- if (__builtin_expect(((w1 - b1) ^ w1) & (b1 << 7), 0)) \
+ if (__builtin_expect(((w1 - b1) & ~w1) & (b1 << 7), 0)) \
{ \
- if ((((w1 - b1) ^ w1) & (b1 << 7)) & mask) \
+ if ((((w1 - b1) & ~w1) & (b1 << 7)) & mask) \
w2 RSHIFT= shift; \
else \
{ \
@@ -284,7 +284,7 @@ strcmp_unaligned(const char* s1, const char* s2)
"bic t1, w1, #"MSB"\n\t"
"cmp t1, w2, "SHFT2LSB" #8\n\t"
"sub r3, w1, b1\n\t"
- "eor r3, r3, w1\n\t"
+ "bic r3, r3, w1\n\t"
"bne 4f\n\t"
"ands r3, r3, b1, lsl #7\n\t"
"it eq\n\t"
@@ -320,7 +320,7 @@ strcmp_unaligned(const char* s1, const char* s2)
SHFT2MSB" t1, w1, #16\n\t"
"sub r3, w1, b1\n\t"
SHFT2LSB" t1, t1, #16\n\t"
- "eor r3, r3, w1\n\t"
+ "bic r3, r3, w1\n\t"
"cmp t1, w2, "SHFT2LSB" #16\n\t"
"bne 4f\n\t"
"ands r3, r3, b1, lsl #7\n\t"
@@ -356,7 +356,7 @@ strcmp_unaligned(const char* s1, const char* s2)
"and t1, w1, #"LSB"\n\t"
"cmp t1, w2, "SHFT2LSB" #24\n\t"
"sub r3, w1, b1\n\t"
- "eor r3, r3, w1\n\t"
+ "bic r3, r3, w1\n\t"
"bne 4f\n\t"
"ands r3, r3, b1, lsl #7\n\t"
"it eq\n\t"
diff --git a/newlib/libc/machine/arm/strcpy.c b/newlib/libc/machine/arm/strcpy.c
index a655a1124..b2e3f5177 100644
--- a/newlib/libc/machine/arm/strcpy.c
+++ b/newlib/libc/machine/arm/strcpy.c
@@ -64,7 +64,7 @@ strcpy (char* dst, const char* src)
"ldr r3, [r1], #4\n\t"
"beq 2f\n\t"
"sub r2, r3, "magic1(r5)"\n\t"
- "eors r2, r2, r3\n\t"
+ "bics r2, r2, r3\n\t"
"tst r2, "magic2(r5)"\n\t"
"itt eq\n\t"
"streq r3, [ip], #4\n\t"
@@ -78,12 +78,12 @@ strcpy (char* dst, const char* src)
"optpld r1, #8\n\t"
"ldr r4, [r1], #4\n\t"
"sub r2, r3, "magic1(r5)"\n\t"
- "eors r2, r2, r3\n\t"
+ "bics r2, r2, r3\n\t"
"tst r2, "magic2(r5)"\n\t"
"sub r2, r4, "magic1(r5)"\n\t"
"bne 1f\n\t"
"str r3, [ip], #4\n\t"
- "eors r2, r2, r4\n\t"
+ "bics r2, r2, r4\n\t"
"tst r2, "magic2(r5)"\n\t"
"itt eq\n\t"
"ldreq r3, [r1], #4\n\t"
diff --git a/newlib/libc/machine/arm/strlen.c b/newlib/libc/machine/arm/strlen.c
index 6442c77ed..f31f72170 100644
--- a/newlib/libc/machine/arm/strlen.c
+++ b/newlib/libc/machine/arm/strlen.c
@@ -79,16 +79,17 @@ strlen (const char* str)
"add ip, len, #4\n\t"
"mov ip, ip, asl #3\n\t"
"mvn r2, #0\n\t"
- "it ne\n\t"
/* ... are masked out */
#ifdef __thumb__
+ "itt ne\n\t"
# ifdef __ARMEB__
"lslne r2, ip\n\t"
# else
"lsrne r2, ip\n\t"
# endif
- "orr data, data, r2\n\t"
+ "orrne data, data, r2\n\t"
#else
+ "it ne\n\t"
# ifdef __ARMEB__
"orrne data, data, r2, lsl ip\n\t"
# else
@@ -104,13 +105,15 @@ strlen (const char* str)
#endif
"orr ip, ip, ip, lsl #16\n"
- /* This is the main loop. We subtract one from each byte in the
- word: the sign bit changes iff the byte was zero. */
+ /* This is the main loop. We subtract one from each byte in
+ the word: the sign bit changes iff the byte was zero or
+ 0x80 -- we eliminate the latter case by anding the result
+ with the 1-s complement of the data. */
"1:\n\t"
/* test (data - 0x01010101) */
"sub r2, data, ip\n\t"
- /* ... ^ data */
- "eor r2, r2, data\n\t"
+ /* ... & ~data */
+ "bic r2, r2, data\n\t"
/* ... & 0x80808080 == 0? */
"ands r2, r2, ip, lsl #7\n\t"
#ifdef _ISA_ARM_7
@@ -124,8 +127,8 @@ strlen (const char* str)
/* test (data - 0x01010101) */
"ittt eq\n\t"
"subeq r2, data, ip\n\t"
- /* ... ^ data */
- "eoreq r2, r2, data\n\t"
+ /* ... & ~data */
+ "biceq r2, r2, data\n\t"
/* ... & 0x80808080 == 0? */
"andeqs r2, r2, ip, lsl #7\n\t"
#endif