Title: [145949] trunk/Source/WTF
Revision
145949
Author
benja...@webkit.org
Date
2013-03-15 15:09:25 -0700 (Fri, 15 Mar 2013)

Log Message

[iOS] Update StringImpl's equal to have a single version on all supported Apple CPUs
https://bugs.webkit.org/show_bug.cgi?id=112400

Patch by Benjamin Poulain <bpoul...@apple.com> on 2013-03-15
Reviewed by Michael Saboff.

* wtf/text/StringImpl.h:
(WTF::equal):
Tweak the code to make it work on older Apple CPUs:
-Use external "ouput" variable instead of the registers R9 and R12. This gets rid
 of some register pressure previously imposed on the compiler. (Clang nicely
 choose R9 and R12 when needed, following iOS ABI).
-Instead of using "R3" for storing the length / 4, update the length by -4 on
 each iteration and work in the negative space for the tail. This frees one register
 which is then used for isEqual.
-Get rid of the unconditional branch from the loop. By using subs and working in the
 negative space, we can test for the Carry flag to jump back to the next LDR.

Modified Paths

Diff

Modified: trunk/Source/WTF/ChangeLog (145948 => 145949)


--- trunk/Source/WTF/ChangeLog	2013-03-15 22:05:36 UTC (rev 145948)
+++ trunk/Source/WTF/ChangeLog	2013-03-15 22:09:25 UTC (rev 145949)
@@ -1,5 +1,24 @@
 2013-03-15  Benjamin Poulain  <bpoul...@apple.com>
 
+        [iOS] Update StringImpl's equal to have a single version on all supported Apple CPUs
+        https://bugs.webkit.org/show_bug.cgi?id=112400
+
+        Reviewed by Michael Saboff.
+
+        * wtf/text/StringImpl.h:
+        (WTF::equal):
+        Tweak the code to make it work on older Apple CPUs:
+        -Use external "ouput" variable instead of the registers R9 and R12. This gets rid
+         of some register pressure previously imposed on the compiler. (Clang nicely
+         choose R9 and R12 when needed, following iOS ABI).
+        -Instead of using "R3" for storing the length / 4, update the length by -4 on
+         each iteration and work in the negative space for the tail. This frees one register
+         which is then used for isEqual.
+        -Get rid of the unconditional branch from the loop. By using subs and working in the
+         negative space, we can test for the Carry flag to jump back to the next LDR.
+
+2013-03-15  Benjamin Poulain  <bpoul...@apple.com>
+
         [iOS] Fix the length pass to memcmp in the fallback versions of String's equal
         https://bugs.webkit.org/show_bug.cgi?id=112463
 

Modified: trunk/Source/WTF/wtf/text/StringImpl.h (145948 => 145949)


--- trunk/Source/WTF/wtf/text/StringImpl.h	2013-03-15 22:05:36 UTC (rev 145948)
+++ trunk/Source/WTF/wtf/text/StringImpl.h	2013-03-15 22:09:25 UTC (rev 145949)
@@ -917,43 +917,52 @@
     
     return true;
 }
-#elif CPU(APPLE_ARMV7S)
+#elif PLATFORM(IOS) && WTF_ARM_ARCH_AT_LEAST(7)
 ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length)
 {
     bool isEqual = false;
-    asm("lsr    r3, %[length], #2\n"
+    uint32_t aValue;
+    uint32_t bValue;
+    asm("subs   %[length], #4\n"
+        "blo    2f\n"
 
-        "0:\n" // Tag 0 = Start of loop over 32 bits.
-        "cbz    r3, 2f\n"
-        "ldr    r9, [%[a]], #4\n"
-        "sub    r3, #1\n"
-        "ldr    r12, [%[b]], #4\n"
-        "cmp    r9, r12\n"
-        "beq    0b\n"
-        "b      66f\n"
+        "0:\n" // Label 0 = Start of loop over 32 bits.
+        "ldr    %[aValue], [%[a]], #4\n"
+        "ldr    %[bValue], [%[b]], #4\n"
+        "cmp    %[aValue], %[bValue]\n"
+        "bne    66f\n"
+        "subs   %[length], #4\n"
+        "bhs    0b\n"
 
-        "2:\n" // Tag 2 = End of loop over 32 bits, check for pair of characters.
+        // At this point, length can be:
+        // -0: 00000000000000000000000000000000 (0 bytes left)
+        // -1: 11111111111111111111111111111111 (3 bytes left)
+        // -2: 11111111111111111111111111111110 (2 bytes left)
+        // -3: 11111111111111111111111111111101 (1 byte left)
+        // -4: 11111111111111111111111111111100 (length was 0)
+        // The pointers are at the correct position.
+        "2:\n" // Label 2 = End of loop over 32 bits, check for pair of characters.
         "tst    %[length], #2\n"
         "beq    1f\n"
-        "ldrh   r9, [%[a]], #2\n"
-        "ldrh   r12, [%[b]], #2\n"
-        "cmp    r9, r12\n"
+        "ldrh   %[aValue], [%[a]], #2\n"
+        "ldrh   %[bValue], [%[b]], #2\n"
+        "cmp    %[aValue], %[bValue]\n"
         "bne    66f\n"
 
-        "1:\n" // Tag 1 = Check for a single character left.
+        "1:\n" // Label 1 = Check for a single character left.
         "tst    %[length], #1\n"
         "beq    42f\n"
-        "ldrb   r9, [%[a]]\n"
-        "ldrb   r12, [%[b]]\n"
-        "cmp    r9, r12\n"
+        "ldrb   %[aValue], [%[a]]\n"
+        "ldrb   %[bValue], [%[b]]\n"
+        "cmp    %[aValue], %[bValue]\n"
         "bne    66f\n"
 
-        "42:\n" // Tag 42 = Success.
+        "42:\n" // Label 42 = Success.
         "mov    %[isEqual], #1\n"
-        "66:\n" // Tag 66 = End without changing isEqual to 1.
-        : [isEqual]"+r"(isEqual), [a]"+r"(a), [b]"+r"(b)
-        : [length]"r"(length)
-        : "r3", "r9", "r12"
+        "66:\n" // Label 66 = End without changing isEqual to 1.
+        : [length]"+r"(length), [isEqual]"+r"(isEqual), [a]"+r"(a), [b]"+r"(b), [aValue]"+r"(aValue), [bValue]"+r"(bValue)
+        :
+        :
         );
     return isEqual;
 }
@@ -962,16 +971,6 @@
 {
     return !memcmp(a, b, length * sizeof(UChar));
 }
-#elif PLATFORM(IOS) && WTF_ARM_ARCH_AT_LEAST(7)
-ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length)
-{
-    return !memcmp(a, b, length);
-}
-
-ALWAYS_INLINE bool equal(const UChar* a, const UChar* b, unsigned length)
-{
-    return !memcmp(a, b, length * sizeof(UChar));
-}
 #else
 ALWAYS_INLINE bool equal(const LChar* a, const LChar* b, unsigned length)
 {
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to