~vorlon/ubuntu/natty/eglibc/multiarch

« back to all changes in this revision

Viewing changes to sysdeps/x86_64/multiarch/strspn-c.c

  • Committer: Steve Langasek
  • Date: 2011-02-18 21:18:44 UTC
  • mfrom: (103.1.7 eglibc)
  • Revision ID: steve.langasek@linaro.org-20110218211844-lodmi8b1qhyq3f3x
Tags: 2.13~pre1-0ubuntu1+multiarch.1
merge from natty

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* strspn with SSE4.2 intrinsics
2
 
   Copyright (C) 2009 Free Software Foundation, Inc.
 
2
   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
3
3
   Contributed by Intel Corporation.
4
4
   This file is part of the GNU C Library.
5
5
 
20
20
 
21
21
#include <nmmintrin.h>
22
22
#include <string.h>
 
23
#include "varshift.h"
23
24
 
24
25
/* We use 0x12:
25
26
        _SIDD_SBYTE_OPS
71
72
      aligned = (const char *) ((size_t) a & -16L);
72
73
      __m128i mask0 = _mm_load_si128 ((__m128i *) aligned);
73
74
 
74
 
      switch (offset)
75
 
        {
76
 
        case 1:
77
 
          mask = _mm_srli_si128 (mask0, 1);
78
 
          break;
79
 
        case 2:
80
 
          mask = _mm_srli_si128 (mask0, 2);
81
 
          break;
82
 
        case 3:
83
 
          mask = _mm_srli_si128 (mask0, 3);
84
 
          break;
85
 
        case 4:
86
 
          mask = _mm_srli_si128 (mask0, 4);
87
 
          break;
88
 
        case 5:
89
 
          mask = _mm_srli_si128 (mask0, 5);
90
 
          break;
91
 
        case 6:
92
 
          mask = _mm_srli_si128 (mask0, 6);
93
 
          break;
94
 
        case 7:
95
 
          mask = _mm_srli_si128 (mask0, 7);
96
 
          break;
97
 
        case 8:
98
 
          mask = _mm_srli_si128 (mask0, 8);
99
 
          break;
100
 
        case 9:
101
 
          mask = _mm_srli_si128 (mask0, 9);
102
 
          break;
103
 
        case 10:
104
 
          mask = _mm_srli_si128 (mask0, 10);
105
 
          break;
106
 
        case 11:
107
 
          mask = _mm_srli_si128 (mask0, 11);
108
 
          break;
109
 
        case 12:
110
 
          mask = _mm_srli_si128 (mask0, 12);
111
 
          break;
112
 
        case 13:
113
 
          mask = _mm_srli_si128 (mask0, 13);
114
 
          break;
115
 
        case 14:
116
 
          mask = _mm_srli_si128 (mask0, 14);
117
 
          break;
118
 
        case 15:
119
 
          mask = _mm_srli_si128 (mask0, 15);
120
 
          break;
121
 
        }
 
75
      mask = __m128i_shift_right (mask0, offset);
122
76
 
123
77
      /* Find where the NULL terminator is.  */
124
78
      int length = _mm_cmpistri (mask, mask, 0x3a);
135
89
 
136
90
          if (index != 0)
137
91
            {
138
 
              /* Combine mask0 and mask1.  */
139
 
              switch (offset)
140
 
                {
141
 
                case 1:
142
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 1);
143
 
                  break;
144
 
                case 2:
145
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 2);
146
 
                  break;
147
 
                case 3:
148
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 3);
149
 
                  break;
150
 
                case 4:
151
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 4);
152
 
                  break;
153
 
                case 5:
154
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 5);
155
 
                  break;
156
 
                case 6:
157
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 6);
158
 
                  break;
159
 
                case 7:
160
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 7);
161
 
                  break;
162
 
                case 8:
163
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 8);
164
 
                  break;
165
 
                case 9:
166
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 9);
167
 
                  break;
168
 
                case 10:
169
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 10);
170
 
                  break;
171
 
                case 11:
172
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 11);
173
 
                  break;
174
 
                case 12:
175
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 12);
176
 
                  break;
177
 
                case 13:
178
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 13);
179
 
                  break;
180
 
                case 14:
181
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 14);
182
 
                  break;
183
 
                case 15:
184
 
                  mask = _mm_alignr_epi8 (mask1, mask0, 15);
185
 
                  break;
186
 
                }
 
92
              /* Combine mask0 and mask1.  We could play games with
 
93
                 palignr, but frankly this data should be in L1 now
 
94
                 so do the merge via an unaligned load.  */
 
95
              mask = _mm_loadu_si128 ((__m128i *) a);
187
96
            }
188
97
        }
189
98
    }
210
119
      aligned = (const char *) ((size_t) s & -16L);
211
120
      __m128i value = _mm_load_si128 ((__m128i *) aligned);
212
121
 
213
 
      switch (offset)
214
 
        {
215
 
        case 1:
216
 
          value = _mm_srli_si128 (value, 1);
217
 
          break;
218
 
        case 2:
219
 
          value = _mm_srli_si128 (value, 2);
220
 
          break;
221
 
        case 3:
222
 
          value = _mm_srli_si128 (value, 3);
223
 
          break;
224
 
        case 4:
225
 
          value = _mm_srli_si128 (value, 4);
226
 
          break;
227
 
        case 5:
228
 
          value = _mm_srli_si128 (value, 5);
229
 
          break;
230
 
        case 6:
231
 
          value = _mm_srli_si128 (value, 6);
232
 
          break;
233
 
        case 7:
234
 
          value = _mm_srli_si128 (value, 7);
235
 
          break;
236
 
        case 8:
237
 
          value = _mm_srli_si128 (value, 8);
238
 
          break;
239
 
        case 9:
240
 
          value = _mm_srli_si128 (value, 9);
241
 
          break;
242
 
        case 10:
243
 
          value = _mm_srli_si128 (value, 10);
244
 
          break;
245
 
        case 11:
246
 
          value = _mm_srli_si128 (value, 11);
247
 
          break;
248
 
        case 12:
249
 
          value = _mm_srli_si128 (value, 12);
250
 
          break;
251
 
        case 13:
252
 
          value = _mm_srli_si128 (value, 13);
253
 
          break;
254
 
        case 14:
255
 
          value = _mm_srli_si128 (value, 14);
256
 
          break;
257
 
        case 15:
258
 
          value = _mm_srli_si128 (value, 15);
259
 
          break;
260
 
        }
 
122
      value = __m128i_shift_right (value, offset);
261
123
 
262
124
      int length = _mm_cmpistri (mask, value, 0x12);
263
125
      /* No need to check CFlag since it is always 1.  */