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.
This commit is contained in:
Jeff Johnston 2009-03-16 20:12:30 +00:00
parent 8213c3f8e3
commit d70118655b
4 changed files with 31 additions and 17 deletions

View File

@ -1,3 +1,14 @@
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.
2009-03-15 Yaakov Selkowitz <yselkowitz@users.sourceforge.net> 2009-03-15 Yaakov Selkowitz <yselkowitz@users.sourceforge.net>
* libc/include/sys/errno.h (ESTRPIPE): Define. * libc/include/sys/errno.h (ESTRPIPE): Define.

View File

@ -97,7 +97,7 @@ __attribute__((naked)) strcmp (const char* s1, const char* s2)
"cmp ip, r3\n\t" "cmp ip, r3\n\t"
"itttt eq\n\t" "itttt eq\n\t"
/* check for any zero bytes in first word */ /* 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" "tsteq r2, "magic2(r4)"\n\t"
"ldreq ip, [r0], #4\n\t" "ldreq ip, [r0], #4\n\t"
"ldreq r3, [r1], #4\n\t" "ldreq r3, [r1], #4\n\t"
@ -171,9 +171,9 @@ strcmp_unaligned(const char* s1, const char* s2)
w2 RSHIFT= shift; \ w2 RSHIFT= shift; \
break; \ 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; \ w2 RSHIFT= shift; \
else \ else \
{ \ { \
@ -284,7 +284,7 @@ strcmp_unaligned(const char* s1, const char* s2)
"bic t1, w1, #"MSB"\n\t" "bic t1, w1, #"MSB"\n\t"
"cmp t1, w2, "SHFT2LSB" #8\n\t" "cmp t1, w2, "SHFT2LSB" #8\n\t"
"sub r3, w1, b1\n\t" "sub r3, w1, b1\n\t"
"eor r3, r3, w1\n\t" "bic r3, r3, w1\n\t"
"bne 4f\n\t" "bne 4f\n\t"
"ands r3, r3, b1, lsl #7\n\t" "ands r3, r3, b1, lsl #7\n\t"
"it eq\n\t" "it eq\n\t"
@ -320,7 +320,7 @@ strcmp_unaligned(const char* s1, const char* s2)
SHFT2MSB" t1, w1, #16\n\t" SHFT2MSB" t1, w1, #16\n\t"
"sub r3, w1, b1\n\t" "sub r3, w1, b1\n\t"
SHFT2LSB" t1, t1, #16\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" "cmp t1, w2, "SHFT2LSB" #16\n\t"
"bne 4f\n\t" "bne 4f\n\t"
"ands r3, r3, b1, lsl #7\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" "and t1, w1, #"LSB"\n\t"
"cmp t1, w2, "SHFT2LSB" #24\n\t" "cmp t1, w2, "SHFT2LSB" #24\n\t"
"sub r3, w1, b1\n\t" "sub r3, w1, b1\n\t"
"eor r3, r3, w1\n\t" "bic r3, r3, w1\n\t"
"bne 4f\n\t" "bne 4f\n\t"
"ands r3, r3, b1, lsl #7\n\t" "ands r3, r3, b1, lsl #7\n\t"
"it eq\n\t" "it eq\n\t"

View File

@ -64,7 +64,7 @@ strcpy (char* dst, const char* src)
"ldr r3, [r1], #4\n\t" "ldr r3, [r1], #4\n\t"
"beq 2f\n\t" "beq 2f\n\t"
"sub r2, r3, "magic1(r5)"\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" "tst r2, "magic2(r5)"\n\t"
"itt eq\n\t" "itt eq\n\t"
"streq r3, [ip], #4\n\t" "streq r3, [ip], #4\n\t"
@ -78,12 +78,12 @@ strcpy (char* dst, const char* src)
"optpld r1, #8\n\t" "optpld r1, #8\n\t"
"ldr r4, [r1], #4\n\t" "ldr r4, [r1], #4\n\t"
"sub r2, r3, "magic1(r5)"\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" "tst r2, "magic2(r5)"\n\t"
"sub r2, r4, "magic1(r5)"\n\t" "sub r2, r4, "magic1(r5)"\n\t"
"bne 1f\n\t" "bne 1f\n\t"
"str r3, [ip], #4\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" "tst r2, "magic2(r5)"\n\t"
"itt eq\n\t" "itt eq\n\t"
"ldreq r3, [r1], #4\n\t" "ldreq r3, [r1], #4\n\t"

View File

@ -79,16 +79,17 @@ strlen (const char* str)
"add ip, len, #4\n\t" "add ip, len, #4\n\t"
"mov ip, ip, asl #3\n\t" "mov ip, ip, asl #3\n\t"
"mvn r2, #0\n\t" "mvn r2, #0\n\t"
"it ne\n\t"
/* ... are masked out */ /* ... are masked out */
#ifdef __thumb__ #ifdef __thumb__
"itt ne\n\t"
# ifdef __ARMEB__ # ifdef __ARMEB__
"lslne r2, ip\n\t" "lslne r2, ip\n\t"
# else # else
"lsrne r2, ip\n\t" "lsrne r2, ip\n\t"
# endif # endif
"orr data, data, r2\n\t" "orrne data, data, r2\n\t"
#else #else
"it ne\n\t"
# ifdef __ARMEB__ # ifdef __ARMEB__
"orrne data, data, r2, lsl ip\n\t" "orrne data, data, r2, lsl ip\n\t"
# else # else
@ -104,13 +105,15 @@ strlen (const char* str)
#endif #endif
"orr ip, ip, ip, lsl #16\n" "orr ip, ip, ip, lsl #16\n"
/* This is the main loop. We subtract one from each byte in the /* This is the main loop. We subtract one from each byte in
word: the sign bit changes iff the byte was zero. */ 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" "1:\n\t"
/* test (data - 0x01010101) */ /* test (data - 0x01010101) */
"sub r2, data, ip\n\t" "sub r2, data, ip\n\t"
/* ... ^ data */ /* ... & ~data */
"eor r2, r2, data\n\t" "bic r2, r2, data\n\t"
/* ... & 0x80808080 == 0? */ /* ... & 0x80808080 == 0? */
"ands r2, r2, ip, lsl #7\n\t" "ands r2, r2, ip, lsl #7\n\t"
#ifdef _ISA_ARM_7 #ifdef _ISA_ARM_7
@ -124,8 +127,8 @@ strlen (const char* str)
/* test (data - 0x01010101) */ /* test (data - 0x01010101) */
"ittt eq\n\t" "ittt eq\n\t"
"subeq r2, data, ip\n\t" "subeq r2, data, ip\n\t"
/* ... ^ data */ /* ... & ~data */
"eoreq r2, r2, data\n\t" "biceq r2, r2, data\n\t"
/* ... & 0x80808080 == 0? */ /* ... & 0x80808080 == 0? */
"andeqs r2, r2, ip, lsl #7\n\t" "andeqs r2, r2, ip, lsl #7\n\t"
#endif #endif