1
1
/* Optimized memchr implementation for PowerPC32/POWER7 using cmpb insn.
2
Copyright (C) 2010 Free Software Foundation, Inc.
2
Copyright (C) 2010-2012 Free Software Foundation, Inc.
3
3
Contributed by Luis Machado <luisgpm@br.ibm.com>.
4
4
This file is part of the GNU C Library.
36
cmplw cr7,r3,r7 /* Is the address equal or less than r3? If
37
it's equal or less, it means size is either 0
38
or a negative number. */
36
cmplw cr7,r3,r7 /* Compare the starting address (r3) with the
37
ending address (r7). If (r3 >= r7), the size
38
passed in is zero or negative. */
41
li r7,-1 /* Make r11 the biggest if r4 <= 0. */
41
li r7,-1 /* Artificially set our ending address (r7)
42
such that we will exit early. */
43
44
rlwinm r6,r3,3,27,28 /* Calculate padding. */
45
cmpli cr6,r6,0 /* cr6 == Do we have padding? */
44
46
lwz r12,0(r8) /* Load word from memory. */
45
47
cmpb r10,r12,r4 /* Check for BYTE's in WORD1. */
48
beq cr6,L(proceed_no_padding)
48
cmplwi cr7,r10,0 /* If r10 == 0, no BYTE's have been found. */
51
L(proceed_no_padding):
52
cmplwi cr7,r10,0 /* If r10 == 0, no BYTEs have been found. */
51
55
/* Are we done already? */
75
79
srwi r6,r5,3 /* Number of loop iterations. */
76
mtctr r6 /* Setup the counter. */
80
mtctr r6 /* Setup the counter. */
78
82
/* Main loop to look for BYTE backwards in the string. Since
79
83
it's a small loop (< 8 instructions), align it to 32-bytes. */
94
98
/* We're here because the counter reached 0, and that means we
95
didn't have any matches for BYTE in the whole range. Just
96
return the original range. */
99
didn't have any matches for BYTE in the whole range. */
99
102
blt cr6,L(loop_small)
118
121
/* r10 has the output of the cmpb instruction, that is, it contains
119
122
0xff in the same position as BYTE in the original
120
123
word from the string. Use that to calculate the pointer.
121
We need to make sure BYTE is *before* the end of the
124
We need to make sure BYTE is *before* the end of the range. */
124
126
cntlzw r0,r10 /* Count leading zeroes before the match. */
125
127
srwi r0,r0,3 /* Convert leading zeroes to bytes. */
142
142
rlwinm r6,r3,3,27,28 /* Calculate padding. */
143
beq L(null) /* This branch is for the cmplwi r5,0 above */
143
144
lwz r12,0(r8) /* Load word from memory. */
145
cmplwi cr6,r6,0 /* cr6 == Do we have padding? */
144
146
cmpb r10,r12,r4 /* Check for BYTE in DWORD1. */
147
beq cr6,L(small_no_padding)
159
L(loop_small): /* loop_small has been unrolled. */
192
/* For most cases we will never get here. Under some combinations of
193
padding + length there is a leftover word that still needs to be
201
/* save a branch and exit directly */
167
205
END (BP_SYM (__memchr))
168
206
weak_alias (BP_SYM (__memchr), BP_SYM(memchr))