~ubuntu-branches/ubuntu/trusty/eglibc/trusty

« back to all changes in this revision

Viewing changes to sysdeps/powerpc/powerpc32/power7/memchr.S

  • Committer: Package Import Robot
  • Author(s): Adam Conrad
  • Date: 2013-01-10 18:39:35 UTC
  • mfrom: (1.5.2) (4.4.24 experimental)
  • Revision ID: package-import@ubuntu.com-20130110183935-afsgfxkmg7wk5eaj
Tags: 2.17-0ubuntu1
* Merge with Debian, bringing in a new upstream and many small fixes:
  - patches/any/cvs-malloc-deadlock.diff: Dropped, merged upstream.
  - patches/ubuntu/lddebug-scopes.diff: Rebase for upstream changes.
  - patches/ubuntu/local-CVE-2012-3406.diff: Rebased against upstream.
  - patches/ubuntu/no-asm-mtune-i686.diff: Fixed in recent binutils.
* This upstream merge fixes a nasty hang in pulseaudio (LP: #1085342)
* Bump MIN_KERNEL_SUPPORTED to 2.6.32 on ARM, now that we no longer
  have to support shonky 2.6.31 kernels on imx51 babbage builders.
* Drop patches/ubuntu/local-disable-nscd-host-caching.diff, as these
  issues were apparently resolved upstream a while ago (LP: #613662)
* Fix the compiled-in bug URL to point to launchpad.net, not Debian.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.
5
5
 
33
33
        cmplwi  r5,16
34
34
        ble     L(small_range)
35
35
 
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.  */
39
39
        ble     cr7,L(proceed)
40
40
 
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. */
42
43
L(proceed):
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)
46
49
        slw     r10,r10,r6
47
50
        srw     r10,r10,r6
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.  */
49
53
        bne     cr7,L(done)
50
54
 
51
55
        /* Are we done already?  */
73
77
L(loop_setup):
74
78
        sub     r5,r7,r9
75
79
        srwi    r6,r5,3       /* Number of loop iterations.  */
76
 
        mtctr   r6            /* Setup the counter.  */
 
80
        mtctr   r6            /* Setup the counter.  */
77
81
        b       L(loop)
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.  */
82
86
        /* Load two words, compare and merge in a
83
87
           single register for speed.  This is an attempt
84
88
           to speed up the byte-checking process for bigger strings.  */
85
 
 
86
89
        lwz     r12,4(r8)
87
90
        lwzu    r11,8(r8)
88
91
        cmpb    r10,r12,r4
91
94
        cmplwi  cr7,r5,0
92
95
        bne     cr7,L(found)
93
96
        bdnz    L(loop)
 
97
 
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.  */
97
 
        addi    r9,r8,4
98
 
        cmplw   cr6,r9,r7
 
99
           didn't have any matches for BYTE in the whole range.  */
 
100
        subi    r11,r7,4
 
101
        cmplw   cr6,r8,r11
99
102
        blt     cr6,L(loop_small)
100
103
        b       L(null)
101
104
 
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
122
 
           range.  */
 
124
           We need to make sure BYTE is *before* the end of the range.  */
123
125
L(done):
124
126
        cntlzw  r0,r10        /* Count leading zeroes before the match.  */
125
127
        srwi    r0,r0,3       /* Convert leading zeroes to bytes.  */
137
139
        .align  4
138
140
L(small_range):
139
141
        cmplwi  r5,0
140
 
        beq     L(null)
141
 
 
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)
145
148
        slw     r10,r10,r6
146
149
        srw     r10,r10,r6
 
150
L(small_no_padding):
147
151
        cmplwi  cr7,r10,0
148
152
        bne     cr7,L(done)
149
153
 
151
155
        addi    r9,r8,4
152
156
        cmplw   r9,r7
153
157
        bge     L(null)
154
 
        b       L(loop_small)
155
 
 
156
 
        .p2align  5
157
 
L(loop_small):
158
 
        lwzu    r12,4(r8)
159
 
        cmpb    r10,r12,r4
160
 
        addi    r9,r8,4
161
 
        cmplwi  cr6,r10,0
162
 
        bne     cr6,L(done)
163
 
        cmplw   r9,r7
164
 
        bge     L(null)
165
 
        b       L(loop_small)
 
158
 
 
159
L(loop_small):                /* loop_small has been unrolled.  */
 
160
        lwzu    r12,4(r8)
 
161
        cmpb    r10,r12,r4
 
162
        addi    r9,r8,4
 
163
        cmplwi  cr6,r10,0
 
164
        cmplw   r9,r7
 
165
        bne     cr6,L(done)
 
166
        bge     L(null)
 
167
 
 
168
        lwzu    r12,4(r8)
 
169
        cmpb    r10,r12,r4
 
170
        addi    r9,r8,4
 
171
        cmplwi  cr6,r10,0
 
172
        cmplw   r9,r7
 
173
        bne     cr6,L(done)
 
174
        bge     L(null)
 
175
 
 
176
        lwzu    r12,4(r8)
 
177
        cmpb    r10,r12,r4
 
178
        addi    r9,r8,4
 
179
        cmplwi  cr6,r10,0
 
180
        cmplw   r9,r7
 
181
        bne     cr6,L(done)
 
182
        bge     L(null)
 
183
 
 
184
        lwzu    r12,4(r8)
 
185
        cmpb    r10,r12,r4
 
186
        addi    r9,r8,4
 
187
        cmplwi  cr6,r10,0
 
188
        cmplw   r9,r7
 
189
        bne     cr6,L(done)
 
190
        bge     L(null)
 
191
 
 
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
 
194
           checked.  */
 
195
        lwzu    r12,4(r8)
 
196
        cmpb    r10,r12,r4
 
197
        addi    r9,r8,4
 
198
        cmplwi  cr6,r10,0
 
199
        bne     cr6,L(done)
 
200
 
 
201
        /* save a branch and exit directly */
 
202
        li      r3,0
 
203
        blr
166
204
 
167
205
END (BP_SYM (__memchr))
168
206
weak_alias (BP_SYM (__memchr), BP_SYM(memchr))