# Optimized strchr implementation for PowerPC. # Copyright (C) 1997 Free Software Foundation, Inc. # This file is part of the GNU C Library. # # The GNU C Library is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public License as # published by the Free Software Foundation; either version 2 of the # License, or (at your option) any later version. # # The GNU C Library is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Library General Public License for more details. # # You should have received a copy of the GNU Library General Public # License along with the GNU C Library; see the file COPYING.LIB. If not, # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. # See strlen.s for comments on how this works. .section ".text" .align 2 .globl strchr .type strchr,@function strchr: # char * [r3] strchr (const char *s [r3] , int c [r4] ) # r0: a temporary # r3: our return result. # r4: byte we're looking for, spread over the whole word # r5: the current word # r6: the constant 0xfefefeff (-0x01010101) # r7: the constant 0x7f7f7f7f # r8: pointer to the current word. # r9: a temporary # r10: the number of bits we should ignore in the first word # r11: a mask with the bits to ignore set to 0 # r12: a temporary rlwimi %r4,%r4,8,16,23 li %r11,-1 rlwimi %r4,%r4,16,0,15 lis %r6,0xfeff lis %r7,0x7f7f clrrwi %r8,%r3,2 addi %r7,%r7,0x7f7f addi %r6,%r6,0xfffffeff rlwinm %r10,%r3,3,27,28 # Test the first (partial?) word. lwz %r5,0(%r8) srw %r11,%r11,%r10 orc %r5,%r5,%r11 add %r0,%r6,%r5 nor %r9,%r7,%r5 and. %r0,%r0,%r9 xor %r12,%r4,%r5 orc %r12,%r12,%r11 b loopentry # The loop. loop: lwzu %r5,4(%r8) and. %r0,%r0,%r9 # Test for 0 add %r0,%r6,%r5 nor %r9,%r7,%r5 bne foundit and. %r0,%r0,%r9 # Start test for the bytes we're looking for xor %r12,%r4,%r5 loopentry: add %r0,%r6,%r12 nor %r9,%r7,%r12 beq loop # There is a zero byte in the word, but may also be a matching byte (either # before or after the zero byte). In fact, we may be looking for a # zero byte, in which case we return a match. We guess that this hasn't # happened, though. missed: and. %r0,%r0,%r9 li %r3,0 beqlr # It did happen. Decide which one was first... # I'm not sure if this is actually faster than a sequence of # rotates, compares, and branches (we use it anyway because it's shorter). and %r6,%r7,%r5 or %r11,%r7,%r5 and %r0,%r7,%r12 or %r10,%r7,%r12 add %r6,%r6,%r7 add %r0,%r0,%r7 nor %r5,%r11,%r6 nor %r9,%r10,%r0 cmplw %r5,%r9 bgtlr cntlzw %r4,%r9 srwi %r4,%r4,3 add %r3,%r8,%r4 blr foundit: and %r0,%r7,%r12 or %r10,%r7,%r12 add %r0,%r0,%r7 nor %r9,%r10,%r0 cntlzw %r4,%r9 subi %r8,%r8,4 srwi %r4,%r4,3 add %r3,%r8,%r4 blr 0: .size strchr,0b-strchr .globl index .weak index .set index,strchr