~linaro-toolchain-dev/cortex-strings/trunk

« back to all changes in this revision

Viewing changes to src/aarch64/strncmp.S

  • Committer: Matthew Gretton-Dann
  • Author(s): Marcus Shawcroft
  • Date: 2013-01-16 20:55:21 UTC
  • mto: This revision was merged to the branch mainline in revision 99.
  • Revision ID: matthew.gretton-dann@linaro.org-20130116205521-mdpiy0qoyg6i62ja
This patch fixes an issue in the AArch64 strncmp implementation which
occurs if  ULONG_MAX-15 <= n <= ULONG_MAX.

Show diffs side-by-side

added added

removed removed

Lines of Context:
77
77
        b.ne    .Lmisaligned8
78
78
        ands    tmp1, src1, #7
79
79
        b.ne    .Lmutual_align
80
 
        add     limit_wd, limit, #7
81
 
        lsr     limit_wd, limit_wd, #3
 
80
        /* Calculate the number of full and partial words -1.  */
 
81
        sub     limit_wd, limit, #1     /* limit != 0, so no underflow.  */
 
82
        lsr     limit_wd, limit_wd, #3  /* Convert to Dwords.  */
 
83
 
82
84
        /* NUL detection works on the principle that (X - 1) & (~X) & 0x80
83
85
           (=> (X - 1) & ~(X | 0x7f)) is non-zero iff a byte is zero, and
84
86
           can be done in parallel across the entire word.  */
91
93
        sub     tmp1, data1, zeroones
92
94
        orr     tmp2, data1, #REP8_7f
93
95
        eor     diff, data1, data2      /* Non-zero if differences found.  */
94
 
        csinv   endloop, diff, xzr, ne  /* Last Dword or differences.  */
 
96
        csinv   endloop, diff, xzr, pl  /* Last Dword or differences.  */
95
97
        bics    has_nul, tmp1, tmp2     /* Non-zero if NUL terminator.  */
96
98
        ccmp    endloop, #0, #0, eq
97
99
        b.eq    .Lloop_aligned
98
100
        /* End of performance-critical section  -- one 64B cache line.  */
99
101
 
100
102
        /* Not reached the limit, must have found the end or a diff.  */
101
 
        cbnz    limit_wd, .Lnot_limit
 
103
        tbz     limit_wd, #63, .Lnot_limit
102
104
 
103
105
        /* Limit % 8 == 0 => all bytes significant.  */
104
106
        ands    limit, limit, #7
173
175
.Lmutual_align:
174
176
        /* Sources are mutually aligned, but are not currently at an
175
177
           alignment boundary.  Round down the addresses and then mask off
176
 
           the bytes that precede the start point.  */
 
178
           the bytes that precede the start point.
 
179
           We also need to adjust the limit calculations, but without
 
180
           overflowing if the limit is near ULONG_MAX.  */
177
181
        bic     src1, src1, #7
178
182
        bic     src2, src2, #7
179
 
        add     limit, limit, tmp1      /* Adjust the limit for the extra.  */
180
 
        lsl     tmp1, tmp1, #3          /* Bytes beyond alignment -> bits.  */
181
183
        ldr     data1, [src1], #8
182
 
        neg     tmp1, tmp1              /* Bits to alignment -64.  */
 
184
        neg     tmp3, tmp1, lsl #3      /* 64 - bits(bytes beyond align). */
183
185
        ldr     data2, [src2], #8
184
186
        mov     tmp2, #~0
 
187
        sub     limit_wd, limit, #1     /* limit != 0, so no underflow.  */
185
188
#ifdef __AARCH64EB__
186
189
        /* Big-endian.  Early bytes are at MSB.  */
187
 
        lsl     tmp2, tmp2, tmp1        /* Shift (tmp1 & 63).  */
 
190
        lsl     tmp2, tmp2, tmp3        /* Shift (tmp1 & 63).  */
188
191
#else
189
192
        /* Little-endian.  Early bytes are at LSB.  */
190
 
        lsr     tmp2, tmp2, tmp1        /* Shift (tmp1 & 63).  */
 
193
        lsr     tmp2, tmp2, tmp3        /* Shift (tmp1 & 63).  */
191
194
#endif
192
 
        add     limit_wd, limit, #7
 
195
        and     tmp3, limit_wd, #7
 
196
        lsr     limit_wd, limit_wd, #3
 
197
        /* Adjust the limit. Only low 3 bits used, so overflow irrelevant.  */
 
198
        add     limit, limit, tmp1
 
199
        add     tmp3, tmp3, tmp1
193
200
        orr     data1, data1, tmp2
194
201
        orr     data2, data2, tmp2
195
 
        lsr     limit_wd, limit_wd, #3
 
202
        add     limit_wd, limit_wd, tmp3, lsr #3
196
203
        b       .Lstart_realigned
197
204
 
198
205
.Lret0: