|
1 /* |
|
2 * LIBOIL - Library of Optimized Inner Loops |
|
3 * Copyright (c) 2004 David A. Schleef <ds@schleef.org> |
|
4 * All rights reserved. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions |
|
8 * are met: |
|
9 * 1. Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * 2. Redistributions in binary form must reproduce the above copyright |
|
12 * notice, this list of conditions and the following disclaimer in the |
|
13 * documentation and/or other materials provided with the distribution. |
|
14 * |
|
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
|
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, |
|
19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
|
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|
21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
|
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
|
23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
|
24 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
25 * POSSIBILITY OF SUCH DAMAGE. |
|
26 */ |
|
27 //Portions Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. |
|
28 |
|
29 #ifdef HAVE_CONFIG_H |
|
30 #include "config.h" |
|
31 #endif |
|
32 |
|
33 #include <liboil/liboil.h> |
|
34 #include "liboil/utf8/utf8.h" |
|
35 |
|
36 |
|
37 #ifdef HAVE_UNALIGNED_ACCESS |
|
38 static void |
|
39 utf8_validate_fast (int32_t *d_1, uint8_t *s, int n) |
|
40 { |
|
41 int i; |
|
42 int extra_bytes; |
|
43 int mask; |
|
44 |
|
45 i=0; |
|
46 while (i<n) { |
|
47 if (i < n-3 && (*(uint32_t *)(s+i) & 0x80808080) == 0) { |
|
48 i+=4; |
|
49 continue; |
|
50 } |
|
51 if (s[i] < 128) { |
|
52 i++; |
|
53 continue; |
|
54 } |
|
55 if ((s[i] & 0xe0) == 0xc0) { |
|
56 extra_bytes = 1; |
|
57 mask = 0x7f; |
|
58 } else if ((s[i] & 0xf0) == 0xe0) { |
|
59 extra_bytes = 2; |
|
60 mask = 0x1f; |
|
61 } else if ((s[i] & 0xf8) == 0xf0) { |
|
62 extra_bytes = 3; |
|
63 mask = 0x0f; |
|
64 } else { |
|
65 goto error; |
|
66 } |
|
67 if (i + extra_bytes >= n) goto error; |
|
68 while(extra_bytes--) { |
|
69 i++; |
|
70 if ((s[i] & 0xc0) != 0x80) goto error; |
|
71 } |
|
72 i++; |
|
73 } |
|
74 |
|
75 error: |
|
76 d_1[0] = i; |
|
77 } |
|
78 OIL_DEFINE_IMPL (utf8_validate_fast, utf8_validate); |
|
79 #endif |
|
80 |
|
81 static void |
|
82 utf8_validate_fast2 (int32_t *d_1, uint8_t *s, int n) |
|
83 { |
|
84 int i; |
|
85 uint8_t x; |
|
86 |
|
87 i=0; |
|
88 while (i<n) { |
|
89 x = s[i]; |
|
90 if (!(x & 0x80)) { |
|
91 i++; |
|
92 continue; |
|
93 } |
|
94 x <<= 1; |
|
95 if (!(x & 0x80)) { |
|
96 goto error; |
|
97 } |
|
98 x <<= 1; |
|
99 if (!(x & 0x80)) { |
|
100 if (i + 1 >= n) goto error; |
|
101 i++; |
|
102 if ((s[i] & 0xc0) != 0x80) goto error; |
|
103 i++; |
|
104 continue; |
|
105 } |
|
106 x <<= 1; |
|
107 if (!(x & 0x80)) { |
|
108 if (i + 2 >= n) goto error; |
|
109 i++; |
|
110 if ((s[i] & 0xc0) != 0x80) goto error; |
|
111 i++; |
|
112 if ((s[i] & 0xc0) != 0x80) goto error; |
|
113 i++; |
|
114 continue; |
|
115 } |
|
116 x <<= 1; |
|
117 if (!(x & 0x80)) { |
|
118 if (i + 3 >= n) goto error; |
|
119 i++; |
|
120 if ((s[i] & 0xc0) != 0x80) goto error; |
|
121 i++; |
|
122 if ((s[i] & 0xc0) != 0x80) goto error; |
|
123 i++; |
|
124 if ((s[i] & 0xc0) != 0x80) goto error; |
|
125 i++; |
|
126 continue; |
|
127 } |
|
128 goto error; |
|
129 } |
|
130 |
|
131 error: |
|
132 d_1[0] = i; |
|
133 } |
|
134 OIL_DEFINE_IMPL (utf8_validate_fast2, utf8_validate); |
|
135 |
|
136 #ifdef HAVE_UNALIGNED_ACCESS |
|
137 static void |
|
138 utf8_validate_fast3 (int32_t *d_1, uint8_t *s, int n) |
|
139 { |
|
140 int i; |
|
141 uint8_t x; |
|
142 |
|
143 i=0; |
|
144 while (i<n) { |
|
145 if (i < n-3 && (*(uint32_t *)(s+i) & 0x80808080) == 0) { |
|
146 i+=4; |
|
147 continue; |
|
148 } |
|
149 x = s[i]; |
|
150 if (!(x & 0x80)) { |
|
151 i++; |
|
152 continue; |
|
153 } |
|
154 if (!(x & 0x40)) { |
|
155 goto error; |
|
156 } |
|
157 if (!(x & 0x20)) { |
|
158 if (i + 1 >= n) goto error; |
|
159 i++; |
|
160 if ((s[i] & 0xc0) != 0x80) goto error; |
|
161 i++; |
|
162 continue; |
|
163 } |
|
164 if (!(x & 0x10)) { |
|
165 if (i + 2 >= n) goto error; |
|
166 i++; |
|
167 if ((s[i] & 0xc0) != 0x80) goto error; |
|
168 i++; |
|
169 if ((s[i] & 0xc0) != 0x80) goto error; |
|
170 i++; |
|
171 continue; |
|
172 } |
|
173 if (!(x & 0x08)) { |
|
174 if (i + 3 >= n) goto error; |
|
175 i++; |
|
176 if ((s[i] & 0xc0) != 0x80) goto error; |
|
177 i++; |
|
178 if ((s[i] & 0xc0) != 0x80) goto error; |
|
179 i++; |
|
180 if ((s[i] & 0xc0) != 0x80) goto error; |
|
181 i++; |
|
182 continue; |
|
183 } |
|
184 goto error; |
|
185 } |
|
186 |
|
187 error: |
|
188 d_1[0] = i; |
|
189 } |
|
190 OIL_DEFINE_IMPL (utf8_validate_fast3, utf8_validate); |
|
191 #endif |
|
192 |
|
193 static uint8_t utf8_table[256] = { |
|
194 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
195 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
196 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
197 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
198 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
199 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
200 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
201 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
|
202 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
|
203 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
|
204 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
|
205 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, |
|
206 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
|
207 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
|
208 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
|
209 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 8, 8, 8, 8, 8, 8 |
|
210 }; |
|
211 |
|
212 static void |
|
213 utf8_validate_lookup (int32_t *d_1, uint8_t *s, int n) |
|
214 { |
|
215 int i; |
|
216 uint8_t x; |
|
217 |
|
218 i=0; |
|
219 while (i<n) { |
|
220 x = utf8_table[s[i]]; |
|
221 if (x > 0) { |
|
222 if (x == 8 || i + x >= n) goto error; |
|
223 while (x>0) { |
|
224 i++; |
|
225 if ((s[i] & 0xc0) != 0x80) goto error; |
|
226 x--; |
|
227 } |
|
228 } |
|
229 i++; |
|
230 } |
|
231 |
|
232 error: |
|
233 d_1[0] = i; |
|
234 } |
|
235 OIL_DEFINE_IMPL (utf8_validate_lookup, utf8_validate); |
|
236 |
|
237 #if 0 |
|
238 static void |
|
239 utf8_validate_asm1 (int32_t *d_1, uint8_t *s, int n) |
|
240 { |
|
241 uint8_t *tmp = s; |
|
242 |
|
243 asm ( |
|
244 "1:\n" |
|
245 " movb (%%eax), %%bl\n" |
|
246 " testb %%bl, %%bl\n" |
|
247 //" jns 3f\n" |
|
248 " js 2f\n" |
|
249 "3:\n" |
|
250 " addl $1, %%eax\n" |
|
251 " subl $1, %%ecx\n" |
|
252 " jne 1b\n" |
|
253 "2:\n" |
|
254 : "+a" (tmp), "+c" (n) |
|
255 : |
|
256 : "ebx" ); |
|
257 |
|
258 d_1[0] = tmp - s; |
|
259 } |
|
260 OIL_DEFINE_IMPL (utf8_validate_asm1, utf8_validate); |
|
261 |
|
262 static void |
|
263 utf8_validate_asm2 (int32_t *d_1, uint8_t *s, int n) |
|
264 { |
|
265 uint8_t *tmp = s; |
|
266 |
|
267 asm ( |
|
268 "1:\n" |
|
269 " testl $0x80808080, (%%eax)\n" |
|
270 " jne 2f\n" |
|
271 " testl $0x80808080, 4(%%eax)\n" |
|
272 " jne 2f\n" |
|
273 " testl $0x80808080, 8(%%eax)\n" |
|
274 " jne 2f\n" |
|
275 " testl $0x80808080, 12(%%eax)\n" |
|
276 " jne 2f\n" |
|
277 " addl $16, %%eax\n" |
|
278 " subl $16, %%ecx\n" |
|
279 " jge 1b\n" |
|
280 " jl 4f\n" |
|
281 "2:\n" |
|
282 " movb (%%eax), %%bl\n" |
|
283 " testb %%bl, %%bl\n" |
|
284 " js 4f\n" |
|
285 "3:\n" |
|
286 " addl $1, %%eax\n" |
|
287 " subl $1, %%ecx\n" |
|
288 " jne 1b\n" |
|
289 "4:\n" |
|
290 : "+a" (tmp), "+c" (n) |
|
291 : |
|
292 : "ebx" ); |
|
293 |
|
294 d_1[0] = tmp - s; |
|
295 } |
|
296 OIL_DEFINE_IMPL (utf8_validate_asm2, utf8_validate); |
|
297 #endif |
|
298 |
|
299 |
|
300 |
|
301 #ifdef HAVE_UNALIGNED_ACCESS |
|
302 #ifdef __SYMBIAN32__ |
|
303 |
|
304 OilFunctionImpl* __oil_function_impl_utf8_validate_fast() { |
|
305 return &_oil_function_impl_utf8_validate_fast; |
|
306 } |
|
307 #endif |
|
308 #endif |
|
309 |
|
310 #ifdef __SYMBIAN32__ |
|
311 |
|
312 OilFunctionImpl* __oil_function_impl_utf8_validate_fast2() { |
|
313 return &_oil_function_impl_utf8_validate_fast2; |
|
314 } |
|
315 #endif |
|
316 |
|
317 #ifdef HAVE_UNALIGNED_ACCESS |
|
318 #ifdef __SYMBIAN32__ |
|
319 |
|
320 OilFunctionImpl* __oil_function_impl_utf8_validate_fast3() { |
|
321 return &_oil_function_impl_utf8_validate_fast3; |
|
322 } |
|
323 #endif |
|
324 #endif |
|
325 |
|
326 #ifdef __SYMBIAN32__ |
|
327 |
|
328 OilFunctionImpl* __oil_function_impl_utf8_validate_lookup() { |
|
329 return &_oil_function_impl_utf8_validate_lookup; |
|
330 } |
|
331 #endif |
|
332 |
|
333 #ifdef __SYMBIAN32__ |
|
334 |
|
335 OilFunctionImpl* __oil_function_impl_utf8_validate_asm1() { |
|
336 return &_oil_function_impl_utf8_validate_asm1; |
|
337 } |
|
338 #endif |
|
339 |
|
340 #ifdef __SYMBIAN32__ |
|
341 |
|
342 OilFunctionImpl* __oil_function_impl_utf8_validate_asm2() { |
|
343 return &_oil_function_impl_utf8_validate_asm2; |
|
344 } |
|
345 #endif |
|
346 |