diff options
Diffstat (limited to 'sysdeps/powerpc/powerpc32/power7/strchrnul.S')
-rw-r--r-- | sysdeps/powerpc/powerpc32/power7/strchrnul.S | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/sysdeps/powerpc/powerpc32/power7/strchrnul.S b/sysdeps/powerpc/powerpc32/power7/strchrnul.S index d4cacab60b..f5d24d4340 100644 --- a/sysdeps/powerpc/powerpc32/power7/strchrnul.S +++ b/sysdeps/powerpc/powerpc32/power7/strchrnul.S @@ -27,8 +27,8 @@ ENTRY (__strchrnul) clrrwi r8,r3,2 /* Align the address to word boundary. */ /* Replicate byte to word. */ - rlwimi r4,r4,8,16,23 - rlwimi r4,r4,16,0,15 + insrdi r4,r4,8,48 + insrdi r4,r4,16,32 rlwinm r6,r3,3,27,28 /* Calculate padding. */ lwz r12,0(r8) /* Load word from memory. */ @@ -43,10 +43,17 @@ ENTRY (__strchrnul) /* Move the words left and right to discard the bits that are not part of the string and bring them back as zeros. */ +#ifdef __LITTLE_ENDIAN__ + srw r10,r10,r6 + srw r9,r9,r6 + slw r10,r10,r6 + slw r9,r9,r6 +#else slw r10,r10,r6 slw r9,r9,r6 srw r10,r10,r6 srw r9,r9,r6 +#endif or r5,r9,r10 /* OR the results to speed things up. */ cmpwi cr7,r5,0 /* If r5 == 0, no c or null bytes have been found. */ @@ -54,7 +61,7 @@ ENTRY (__strchrnul) mtcrf 0x01,r8 - /* Are we now aligned to a quadword boundary? If so, skip to + /* Are we now aligned to a doubleword boundary? If so, skip to the main loop. Otherwise, go through the alignment code. */ bt 29,L(loop) @@ -76,7 +83,7 @@ L(loop): single register for speed. This is an attempt to speed up the null-checking process for bigger strings. */ lwz r12,4(r8) - lwzu r11,8(r8) + lwzu r11,8(r8) cmpb r10,r12,r0 cmpb r9,r12,r4 cmpb r6,r11,r0 @@ -95,9 +102,9 @@ L(loop): addi r8,r8,-4 bne cr6,L(done) - /* The c/null byte must be in the second word. Adjust the - address again and move the result of cmpb to r10 so we can calculate - the pointer. */ + /* The c/null byte must be in the second word. Adjust the address + again and move the result of cmpb to r5 so we can calculate the + pointer. */ mr r5,r10 addi r8,r8,4 @@ -105,7 +112,13 @@ L(loop): 0xff in the same position as the c/null byte in the original word from the string. Use that to calculate the pointer. */ L(done): +#ifdef __LITTLE_ENDIAN__ + addi r0,r5,-1 + andc r0,r0,r5 + popcntw r0,r0 +#else cntlzw r0,r5 /* Count leading zeros before the match. */ +#endif srwi r0,r0,3 /* Convert leading zeros to bytes. */ add r3,r8,r0 /* Return address of matching c/null byte. */ blr |