diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2009-03-16 23:12:30 +0300 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2009-03-16 23:12:30 +0300 |
commit | d70118655b0d30849c5a85e2afbb72b91e395a63 (patch) | |
tree | fba90704b6bcbd7c14def7c3b1d105a49c9ed564 /newlib/libc/machine | |
parent | 8213c3f8e3e8e9276e27d6920ff2008ed234e4a3 (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.c | 12 | ||||
-rw-r--r-- | newlib/libc/machine/arm/strcpy.c | 6 | ||||
-rw-r--r-- | newlib/libc/machine/arm/strlen.c | 19 |
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 |