1 /*
2 * Copyright (C) 2020 Linux Studio Plugins Project <https://lsp-plug.in/>
3 * (C) 2020 Vladimir Sadovnikov <sadko4u@gmail.com>
4 *
5 * This file is part of lsp-plugins
6 * Created on: 06 февр. 2016 г.
7 *
8 * lsp-plugins is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * any later version.
12 *
13 * lsp-plugins is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with lsp-plugins. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #ifndef DSP_ARCH_X86_BITS_H_
23 #define DSP_ARCH_X86_BITS_H_
24
reverse_bits(uint8_t v)25 inline uint8_t __lsp_forced_inline reverse_bits(uint8_t v)
26 {
27 register size_t tmp;
28
29 ARCH_X86_ASM (
30 __ASM_EMIT("movzx %[v], %[tmp]")
31 __ASM_EMIT("mov (%[rb], %[tmp]), %[v]")
32 : [v] "+q"(v), [tmp] "=&r"(tmp)
33 : [rb] "r"(__rb)
34 : "cc"
35 );
36
37 return v;
38 }
39
reverse_bits(int8_t v)40 inline int8_t __lsp_forced_inline reverse_bits(int8_t v)
41 {
42 register size_t tmp;
43
44 ARCH_X86_ASM (
45 __ASM_EMIT("movzx %[v], %[tmp]")
46 __ASM_EMIT("mov (%[rb], %[tmp]), %[v]")
47 : [v] "+q"(v), [tmp] "=&r"(tmp)
48 : [rb] "r"(__rb)
49 : "cc"
50 );
51
52 return v;
53 }
54
reverse_bits(uint8_t v,size_t count)55 inline uint8_t __lsp_forced_inline reverse_bits(uint8_t v, size_t count)
56 {
57 register size_t tmp;
58
59 ARCH_X86_ASM (
60 __ASM_EMIT("movzx %[v], %[tmp]")
61 __ASM_EMIT("mov (%[rb], %[tmp]), %[v]")
62 __ASM_EMIT("shr %%cl, %[v]")
63 : [v] "+q"(v), [tmp] "=&r"(tmp)
64 : [rb] "r"(__rb), "c"(8-count)
65 : "cc"
66 );
67
68 return v;
69 }
70
reverse_bits(int8_t v,size_t count)71 inline int8_t __lsp_forced_inline reverse_bits(int8_t v, size_t count)
72 {
73 register size_t tmp;
74
75 ARCH_X86_ASM (
76 __ASM_EMIT("movzx %[v], %[tmp]")
77 __ASM_EMIT("mov (%[rb], %[tmp]), %[v]")
78 __ASM_EMIT("shr %%cl, %[v]")
79 : [v] "+q"(v), [tmp] "=&r"(tmp)
80 : [rb] "r"(__rb), "c"(8-count)
81 : "cc"
82 );
83
84 return v;
85 }
86
reverse_bits(uint16_t v)87 inline uint16_t __lsp_forced_inline reverse_bits(uint16_t v)
88 {
89 #ifdef ARCH_X86_64
90 register size_t tmp;
91
92 ARCH_X86_ASM (
93 __ASM_EMIT("movzx %%al, %[tmp]")
94 __ASM_EMIT("mov (%[rb], %[tmp]), %%al")
95 __ASM_EMIT("ror $8, %%ax")
96 __ASM_EMIT("movzx %%al, %[tmp]")
97 __ASM_EMIT("mov (%[rb], %[tmp]), %%al")
98
99 : [v] "+a"(v), [tmp] "=&r"(tmp)
100 : [rb] "r"(__rb)
101 : "cc"
102 );
103 #else
104 register size_t tmp1, tmp2;
105
106 ARCH_X86_ASM (
107 __ASM_EMIT("movzx %%al, %[tmp1]")
108 __ASM_EMIT("movzx %%ah, %[tmp2]")
109 __ASM_EMIT("mov (%[rb], %[tmp1]), %%ah")
110 __ASM_EMIT("mov (%[rb], %[tmp2]), %%al")
111 : [v] "+a"(v), [tmp1] "=&r"(tmp1), [tmp2] "=&r"(tmp2)
112 : [rb] "r"(__rb)
113 : "cc"
114 );
115 #endif /* ARCH_X86_64 */
116
117 return v;
118 }
119
reverse_bits(int16_t v)120 inline int16_t __lsp_forced_inline reverse_bits(int16_t v)
121 {
122 #ifdef ARCH_X86_64
123 register size_t tmp;
124
125 ARCH_X86_ASM (
126 __ASM_EMIT("movzx %%al, %[tmp]")
127 __ASM_EMIT("mov (%[rb], %[tmp]), %%al")
128 __ASM_EMIT("ror $8, %%ax")
129 __ASM_EMIT("movzx %%al, %[tmp]")
130 __ASM_EMIT("mov (%[rb], %[tmp]), %%al")
131
132 : [v] "+a"(v), [tmp] "=&r"(tmp)
133 : [rb] "r"(__rb)
134 : "cc"
135 );
136 #else
137 register size_t tmp1, tmp2;
138
139 ARCH_X86_ASM (
140 __ASM_EMIT("movzx %%al, %[tmp1]")
141 __ASM_EMIT("movzx %%ah, %[tmp2]")
142 __ASM_EMIT("mov (%[rb], %[tmp1]), %%ah")
143 __ASM_EMIT("mov (%[rb], %[tmp2]), %%al")
144 : [v] "+a"(v), [tmp1] "=&r"(tmp1), [tmp2] "=&r"(tmp2)
145 : [rb] "r"(__rb)
146 : "cc"
147 );
148 #endif /* ARCH_X86_64 */
149
150 return v;
151 }
152
reverse_bits(uint16_t v,size_t count)153 inline uint16_t __lsp_forced_inline reverse_bits(uint16_t v, size_t count)
154 {
155 #ifdef ARCH_X86_64
156 register size_t tmp;
157
158 ARCH_X86_ASM (
159 __ASM_EMIT("movzx %%al, %[tmp]")
160 __ASM_EMIT("mov (%[rb], %[tmp]), %%al")
161 __ASM_EMIT("ror $8, %%ax")
162 __ASM_EMIT("movzx %%al, %[tmp]")
163 __ASM_EMIT("mov (%[rb], %[tmp]), %%al")
164 __ASM_EMIT("shr %%cl, %[v]")
165
166 : [v] "+a"(v), [tmp] "=&r"(tmp)
167 : [rb] "r"(__rb), "c"(16 - count)
168 : "cc"
169 );
170 #else
171 register size_t tmp1, tmp2;
172
173 ARCH_X86_ASM (
174 __ASM_EMIT("movzx %%al, %[tmp1]")
175 __ASM_EMIT("movzx %%ah, %[tmp2]")
176 __ASM_EMIT("mov (%[rb], %[tmp1]), %%ah")
177 __ASM_EMIT("mov (%[rb], %[tmp2]), %%al")
178 __ASM_EMIT("shr %%cl, %[v]")
179 : [v] "+a"(v), [tmp1] "=&r"(tmp1), [tmp2] "=&r"(tmp2)
180 : [rb] "r"(__rb), "c"(16 - count)
181 : "cc"
182 );
183 #endif /* ARCH_X86_64 */
184
185 return v;
186 }
187
reverse_bits(int16_t v,size_t count)188 inline int16_t __lsp_forced_inline reverse_bits(int16_t v, size_t count)
189 {
190 #ifdef ARCH_X86_64
191 register size_t tmp;
192
193 ARCH_X86_ASM (
194 __ASM_EMIT("movzx %%al, %[tmp]")
195 __ASM_EMIT("mov (%[rb], %[tmp]), %%al")
196 __ASM_EMIT("ror $8, %%ax")
197 __ASM_EMIT("movzx %%al, %[tmp]")
198 __ASM_EMIT("mov (%[rb], %[tmp]), %%al")
199 __ASM_EMIT("shr %%cl, %[v]")
200
201 : [v] "+a"(v), [tmp] "=&r"(tmp)
202 : [rb] "r"(__rb), "c"(16 - count)
203 : "cc"
204 );
205 #else
206 register size_t tmp1, tmp2;
207
208 ARCH_X86_ASM (
209 __ASM_EMIT("movzx %%al, %[tmp1]")
210 __ASM_EMIT("movzx %%ah, %[tmp2]")
211 __ASM_EMIT("mov (%[rb], %[tmp1]), %%ah")
212 __ASM_EMIT("mov (%[rb], %[tmp2]), %%al")
213 __ASM_EMIT("shr %%cl, %[v]")
214 : [v] "+a"(v), [tmp1] "=&r"(tmp1), [tmp2] "=&r"(tmp2)
215 : [rb] "r"(__rb), "c"(16 - count)
216 : "cc"
217 );
218 #endif /* ARCH_X86_64 */
219
220 return v;
221 }
222
reverse_bits(uint32_t v)223 inline uint32_t __lsp_forced_inline reverse_bits(uint32_t v)
224 {
225 register uint32_t tmp;
226
227 ARCH_X86_ASM (
228 __ASM_EMIT("bswap %0")
229
230 __ASM_EMIT("mov %0, %1")
231 __ASM_EMIT("and $0xf0f0f0f0, %0")
232 __ASM_EMIT("and $0x0f0f0f0f, %1")
233 __ASM_EMIT("shr $4, %0")
234 __ASM_EMIT("shl $4, %1")
235 __ASM_EMIT("or %1, %0")
236
237 __ASM_EMIT("mov %0, %1")
238 __ASM_EMIT("and $0xcccccccc, %0")
239 __ASM_EMIT("and $0x33333333, %1")
240 __ASM_EMIT("shr $2, %0")
241 __ASM_EMIT("lea (%0, %1, 4), %0")
242
243 __ASM_EMIT("mov %0, %1")
244 __ASM_EMIT("and $0xaaaaaaaa, %0")
245 __ASM_EMIT("and $0x55555555, %1")
246 __ASM_EMIT("shr $1, %0")
247 __ASM_EMIT("lea (%0, %1, 2), %0")
248
249 : "+r"(v), "=&r"(tmp)
250 :
251 : "cc"
252 );
253 return v;
254 }
255
reverse_bits(int32_t v)256 inline int32_t __lsp_forced_inline reverse_bits(int32_t v)
257 {
258 register uint32_t tmp;
259
260 ARCH_X86_ASM (
261 __ASM_EMIT("bswap %0")
262
263 __ASM_EMIT("mov %0, %1")
264 __ASM_EMIT("and $0xf0f0f0f0, %0")
265 __ASM_EMIT("and $0x0f0f0f0f, %1")
266 __ASM_EMIT("shr $4, %0")
267 __ASM_EMIT("shl $4, %1")
268 __ASM_EMIT("or %1, %0")
269
270 __ASM_EMIT("mov %0, %1")
271 __ASM_EMIT("and $0xcccccccc, %0")
272 __ASM_EMIT("and $0x33333333, %1")
273 __ASM_EMIT("shr $2, %0")
274 __ASM_EMIT("lea (%0, %1, 4), %0")
275
276 __ASM_EMIT("mov %0, %1")
277 __ASM_EMIT("and $0xaaaaaaaa, %0")
278 __ASM_EMIT("and $0x55555555, %1")
279 __ASM_EMIT("shr $1, %0")
280 __ASM_EMIT("lea (%0, %1, 2), %0")
281
282 : "+r"(v), "=&r"(tmp)
283 :
284 : "cc"
285 );
286 return v;
287 }
288
reverse_bits(uint32_t v,size_t count)289 inline uint32_t __lsp_forced_inline reverse_bits(uint32_t v, size_t count)
290 {
291 register uint32_t tmp;
292
293 ARCH_X86_ASM (
294 __ASM_EMIT("bswap %0")
295
296 __ASM_EMIT("mov %0, %1")
297 __ASM_EMIT("and $0xf0f0f0f0, %0")
298 __ASM_EMIT("and $0x0f0f0f0f, %1")
299 __ASM_EMIT("shr $4, %0")
300 __ASM_EMIT("shl $4, %1")
301 __ASM_EMIT("or %1, %0")
302
303 __ASM_EMIT("mov %0, %1")
304 __ASM_EMIT("and $0xcccccccc, %0")
305 __ASM_EMIT("and $0x33333333, %1")
306 __ASM_EMIT("shr $2, %0")
307 __ASM_EMIT("lea (%0, %1, 4), %0")
308
309 __ASM_EMIT("mov %0, %1")
310 __ASM_EMIT("and $0xaaaaaaaa, %0")
311 __ASM_EMIT("and $0x55555555, %1")
312 __ASM_EMIT("shr $1, %0")
313 __ASM_EMIT("lea (%0, %1, 2), %0")
314
315 __ASM_EMIT("shr %%cl, %0")
316
317 : "+r"(v), "=&r"(tmp)
318 : "c"(32-count)
319 : "cc"
320 );
321 return v;
322 }
323
reverse_bits(int32_t v,size_t count)324 inline int32_t __lsp_forced_inline reverse_bits(int32_t v, size_t count)
325 {
326 register uint32_t tmp;
327
328 ARCH_X86_ASM (
329 __ASM_EMIT("bswap %0")
330
331 __ASM_EMIT("mov %0, %1")
332 __ASM_EMIT("and $0xf0f0f0f0, %0")
333 __ASM_EMIT("and $0x0f0f0f0f, %1")
334 __ASM_EMIT("shr $4, %0")
335 __ASM_EMIT("shl $4, %1")
336 __ASM_EMIT("or %1, %0")
337
338 __ASM_EMIT("mov %0, %1")
339 __ASM_EMIT("and $0xcccccccc, %0")
340 __ASM_EMIT("and $0x33333333, %1")
341 __ASM_EMIT("shr $2, %0")
342 __ASM_EMIT("lea (%0, %1, 4), %0")
343
344 __ASM_EMIT("mov %0, %1")
345 __ASM_EMIT("and $0xaaaaaaaa, %0")
346 __ASM_EMIT("and $0x55555555, %1")
347 __ASM_EMIT("shr $1, %0")
348 __ASM_EMIT("lea (%0, %1, 2), %0")
349
350 __ASM_EMIT("shr %%cl, %0")
351
352 : "+r"(v), "=&r"(tmp)
353 : "c"(32-count)
354 : "cc"
355 );
356 return v;
357 }
358
359 #ifdef ARCH_I386
reverse_bits(uint64_t v)360 inline uint64_t __lsp_forced_inline reverse_bits(uint64_t v)
361 {
362 register uint32_t tmp1, tmp2;
363
364 ARCH_X86_ASM
365 (
366 __ASM_EMIT("bswap %%eax")
367 __ASM_EMIT("bswap %%edx")
368 __ASM_EMIT("xchg %%edx, %%eax")
369
370 __ASM_EMIT("mov %%eax, %1")
371 __ASM_EMIT("mov %%edx, %2")
372 __ASM_EMIT("and $0xf0f0f0f0, %%eax")
373 __ASM_EMIT("and $0xf0f0f0f0, %%edx")
374 __ASM_EMIT("and $0x0f0f0f0f, %1")
375 __ASM_EMIT("and $0x0f0f0f0f, %2")
376 __ASM_EMIT("shr $4, %%eax")
377 __ASM_EMIT("shr $4, %%edx")
378 __ASM_EMIT("shl $4, %1")
379 __ASM_EMIT("shl $4, %2")
380 __ASM_EMIT("or %1, %%eax")
381 __ASM_EMIT("or %2, %%edx")
382
383 __ASM_EMIT("mov %%eax, %1")
384 __ASM_EMIT("mov %%edx, %2")
385 __ASM_EMIT("and $0xcccccccc, %%eax")
386 __ASM_EMIT("and $0xcccccccc, %%edx")
387 __ASM_EMIT("and $0x33333333, %1")
388 __ASM_EMIT("and $0x33333333, %2")
389 __ASM_EMIT("shr $2, %%eax")
390 __ASM_EMIT("shr $2, %%edx")
391 __ASM_EMIT("lea (%%eax, %1, 4), %%eax")
392 __ASM_EMIT("lea (%%edx, %2, 4), %%edx")
393
394 __ASM_EMIT("mov %%eax, %1")
395 __ASM_EMIT("mov %%edx, %2")
396 __ASM_EMIT("and $0xaaaaaaaa, %%eax")
397 __ASM_EMIT("and $0xaaaaaaaa, %%edx")
398 __ASM_EMIT("and $0x55555555, %1")
399 __ASM_EMIT("and $0x55555555, %2")
400 __ASM_EMIT("shr $1, %%eax")
401 __ASM_EMIT("shr $1, %%edx")
402 __ASM_EMIT("lea (%%eax, %1, 2), %%eax")
403 __ASM_EMIT("lea (%%edx, %2, 2), %%edx")
404
405 : "+A"(v), "=&r"(tmp1), "=&r"(tmp2)
406 :
407 : "cc"
408 );
409
410 return v;
411 }
412
reverse_bits(int64_t v)413 inline int64_t __lsp_forced_inline reverse_bits(int64_t v)
414 {
415 register uint32_t tmp1, tmp2;
416
417 ARCH_X86_ASM
418 (
419 __ASM_EMIT("bswap %%eax")
420 __ASM_EMIT("bswap %%edx")
421 __ASM_EMIT("xchg %%edx, %%eax")
422
423 __ASM_EMIT("mov %%eax, %1")
424 __ASM_EMIT("mov %%edx, %2")
425 __ASM_EMIT("and $0xf0f0f0f0, %%eax")
426 __ASM_EMIT("and $0xf0f0f0f0, %%edx")
427 __ASM_EMIT("and $0x0f0f0f0f, %1")
428 __ASM_EMIT("and $0x0f0f0f0f, %2")
429 __ASM_EMIT("shr $4, %%eax")
430 __ASM_EMIT("shr $4, %%edx")
431 __ASM_EMIT("shl $4, %1")
432 __ASM_EMIT("shl $4, %2")
433 __ASM_EMIT("or %1, %%eax")
434 __ASM_EMIT("or %2, %%edx")
435
436 __ASM_EMIT("mov %%eax, %1")
437 __ASM_EMIT("mov %%edx, %2")
438 __ASM_EMIT("and $0xcccccccc, %%eax")
439 __ASM_EMIT("and $0xcccccccc, %%edx")
440 __ASM_EMIT("and $0x33333333, %1")
441 __ASM_EMIT("and $0x33333333, %2")
442 __ASM_EMIT("shr $2, %%eax")
443 __ASM_EMIT("shr $2, %%edx")
444 __ASM_EMIT("lea (%%eax, %1, 4), %%eax")
445 __ASM_EMIT("lea (%%edx, %2, 4), %%edx")
446
447 __ASM_EMIT("mov %%eax, %1")
448 __ASM_EMIT("mov %%edx, %2")
449 __ASM_EMIT("and $0xaaaaaaaa, %%eax")
450 __ASM_EMIT("and $0xaaaaaaaa, %%edx")
451 __ASM_EMIT("and $0x55555555, %1")
452 __ASM_EMIT("and $0x55555555, %2")
453 __ASM_EMIT("shr $1, %%eax")
454 __ASM_EMIT("shr $1, %%edx")
455 __ASM_EMIT("lea (%%eax, %1, 2), %%eax")
456 __ASM_EMIT("lea (%%edx, %2, 2), %%edx")
457
458 : "+A"(v), "=&r"(tmp1), "=&r"(tmp2)
459 :
460 : "cc"
461 );
462
463 return v;
464 }
465
reverse_bits(uint64_t v,size_t count)466 inline uint64_t __lsp_forced_inline reverse_bits(uint64_t v, size_t count)
467 {
468 register uint32_t tmp1, tmp2;
469 count = 64 - count;
470
471 if (count < 32)
472 {
473 ARCH_X86_ASM
474 (
475 __ASM_EMIT("bswap %%eax")
476 __ASM_EMIT("bswap %%edx")
477 __ASM_EMIT("xchg %%edx, %%eax")
478
479 __ASM_EMIT("mov %%eax, %[t1]")
480 __ASM_EMIT("mov %%edx, %[t2]")
481 __ASM_EMIT("and $0xf0f0f0f0, %%eax")
482 __ASM_EMIT("and $0xf0f0f0f0, %%edx")
483 __ASM_EMIT("and $0x0f0f0f0f, %[t1]")
484 __ASM_EMIT("and $0x0f0f0f0f, %[t2]")
485 __ASM_EMIT("shr $4, %%eax")
486 __ASM_EMIT("shr $4, %%edx")
487 __ASM_EMIT("shl $4, %[t1]")
488 __ASM_EMIT("shl $4, %[t2]")
489 __ASM_EMIT("or %[t1], %%eax")
490 __ASM_EMIT("or %[t2], %%edx")
491
492 __ASM_EMIT("mov %%eax, %[t1]")
493 __ASM_EMIT("mov %%edx, %[t2]")
494 __ASM_EMIT("and $0xcccccccc, %%eax")
495 __ASM_EMIT("and $0xcccccccc, %%edx")
496 __ASM_EMIT("and $0x33333333, %[t1]")
497 __ASM_EMIT("and $0x33333333, %[t2]")
498 __ASM_EMIT("shr $2, %%eax")
499 __ASM_EMIT("shr $2, %%edx")
500 __ASM_EMIT("lea (%%eax, %[t1], 4), %%eax")
501 __ASM_EMIT("lea (%%edx, %[t2], 4), %%edx")
502
503 __ASM_EMIT("mov %%eax, %[t1]")
504 __ASM_EMIT("mov %%edx, %[t2]")
505 __ASM_EMIT("and $0xaaaaaaaa, %%eax")
506 __ASM_EMIT("and $0xaaaaaaaa, %%edx")
507 __ASM_EMIT("and $0x55555555, %[t1]")
508 __ASM_EMIT("and $0x55555555, %[t2]")
509 __ASM_EMIT("shr $1, %%eax")
510 __ASM_EMIT("shr $1, %%edx")
511 __ASM_EMIT("lea (%%eax, %[t1], 2), %%eax")
512 __ASM_EMIT("lea (%%edx, %[t2], 2), %%edx")
513
514 __ASM_EMIT("shrd %%cl, %%edx, %%eax")
515 __ASM_EMIT("shr %%cl, %%edx")
516
517 : [v] "+A"(v), [t1] "=&r"(tmp1), [t2] "=&r"(tmp2)
518 : [c] "c" (count)
519 : "cc"
520 );
521 }
522 else
523 {
524 ARCH_X86_ASM
525 (
526 __ASM_EMIT("bswap %%eax")
527 __ASM_EMIT("sub $32, %[c]")
528
529 __ASM_EMIT("mov %%eax, %%edx")
530 __ASM_EMIT("and $0xf0f0f0f0, %%eax")
531 __ASM_EMIT("and $0x0f0f0f0f, %%edx")
532 __ASM_EMIT("shr $4, %%eax")
533 __ASM_EMIT("shl $4, %%edx")
534 __ASM_EMIT("or %%edx, %%eax")
535
536 __ASM_EMIT("mov %%eax, %%edx")
537 __ASM_EMIT("and $0xcccccccc, %%eax")
538 __ASM_EMIT("and $0x33333333, %%edx")
539 __ASM_EMIT("shr $2, %%eax")
540 __ASM_EMIT("lea (%%eax, %%edx, 4), %%eax")
541
542 __ASM_EMIT("mov %%eax, %%edx")
543 __ASM_EMIT("and $0xaaaaaaaa, %%eax")
544 __ASM_EMIT("and $0x55555555, %%edx")
545 __ASM_EMIT("shr $1, %%eax")
546 __ASM_EMIT("lea (%%eax, %%edx, 2), %%eax")
547
548 __ASM_EMIT("xor %%edx, %%edx")
549 __ASM_EMIT("shr %%cl, %%eax")
550
551 : [v] "+A"(v), [c] "+c" (count)
552 :
553 : "cc"
554 );
555 }
556
557 return v;
558 }
559
reverse_bits(int64_t v,size_t count)560 inline int64_t __lsp_forced_inline reverse_bits(int64_t v, size_t count)
561 {
562 register uint32_t tmp1, tmp2;
563 count = 64 - count;
564
565 if (count < 32)
566 {
567 ARCH_X86_ASM
568 (
569 __ASM_EMIT("bswap %%eax")
570 __ASM_EMIT("bswap %%edx")
571 __ASM_EMIT("xchg %%edx, %%eax")
572
573 __ASM_EMIT("mov %%eax, %[t1]")
574 __ASM_EMIT("mov %%edx, %[t2]")
575 __ASM_EMIT("and $0xf0f0f0f0, %%eax")
576 __ASM_EMIT("and $0xf0f0f0f0, %%edx")
577 __ASM_EMIT("and $0x0f0f0f0f, %[t1]")
578 __ASM_EMIT("and $0x0f0f0f0f, %[t2]")
579 __ASM_EMIT("shr $4, %%eax")
580 __ASM_EMIT("shr $4, %%edx")
581 __ASM_EMIT("shl $4, %[t1]")
582 __ASM_EMIT("shl $4, %[t2]")
583 __ASM_EMIT("or %[t1], %%eax")
584 __ASM_EMIT("or %[t2], %%edx")
585
586 __ASM_EMIT("mov %%eax, %[t1]")
587 __ASM_EMIT("mov %%edx, %[t2]")
588 __ASM_EMIT("and $0xcccccccc, %%eax")
589 __ASM_EMIT("and $0xcccccccc, %%edx")
590 __ASM_EMIT("and $0x33333333, %[t1]")
591 __ASM_EMIT("and $0x33333333, %[t2]")
592 __ASM_EMIT("shr $2, %%eax")
593 __ASM_EMIT("shr $2, %%edx")
594 __ASM_EMIT("lea (%%eax, %[t1], 4), %%eax")
595 __ASM_EMIT("lea (%%edx, %[t2], 4), %%edx")
596
597 __ASM_EMIT("mov %%eax, %[t1]")
598 __ASM_EMIT("mov %%edx, %[t2]")
599 __ASM_EMIT("and $0xaaaaaaaa, %%eax")
600 __ASM_EMIT("and $0xaaaaaaaa, %%edx")
601 __ASM_EMIT("and $0x55555555, %[t1]")
602 __ASM_EMIT("and $0x55555555, %[t2]")
603 __ASM_EMIT("shr $1, %%eax")
604 __ASM_EMIT("shr $1, %%edx")
605 __ASM_EMIT("lea (%%eax, %[t1], 2), %%eax")
606 __ASM_EMIT("lea (%%edx, %[t2], 2), %%edx")
607
608 __ASM_EMIT("shrd %%cl, %%edx, %%eax")
609 __ASM_EMIT("shr %%cl, %%edx")
610
611 : [v] "+A"(v), [t1] "=&r"(tmp1), [t2] "=&r"(tmp2)
612 : [c] "c" (count)
613 : "cc"
614 );
615 }
616 else
617 {
618 ARCH_X86_ASM
619 (
620 __ASM_EMIT("bswap %%eax")
621 __ASM_EMIT("sub $32, %[c]")
622
623 __ASM_EMIT("mov %%eax, %%edx")
624 __ASM_EMIT("and $0xf0f0f0f0, %%eax")
625 __ASM_EMIT("and $0x0f0f0f0f, %%edx")
626 __ASM_EMIT("shr $4, %%eax")
627 __ASM_EMIT("shl $4, %%edx")
628 __ASM_EMIT("or %%edx, %%eax")
629
630 __ASM_EMIT("mov %%eax, %%edx")
631 __ASM_EMIT("and $0xcccccccc, %%eax")
632 __ASM_EMIT("and $0x33333333, %%edx")
633 __ASM_EMIT("shr $2, %%eax")
634 __ASM_EMIT("lea (%%eax, %%edx, 4), %%eax")
635
636 __ASM_EMIT("mov %%eax, %%edx")
637 __ASM_EMIT("and $0xaaaaaaaa, %%eax")
638 __ASM_EMIT("and $0x55555555, %%edx")
639 __ASM_EMIT("shr $1, %%eax")
640 __ASM_EMIT("lea (%%eax, %%edx, 2), %%eax")
641
642 __ASM_EMIT("xor %%edx, %%edx")
643 __ASM_EMIT("shr %%cl, %%eax")
644
645 : [v] "+A"(v), [c] "+c" (count)
646 :
647 : "cc"
648 );
649 }
650
651 return v;
652 }
653 #else /* ARCH_X86_64 */
reverse_bits(uint64_t v)654 inline uint64_t __lsp_forced_inline reverse_bits(uint64_t v)
655 {
656 register uint64_t tmp;
657
658 ARCH_X86_ASM (
659 __ASM_EMIT("bswap %0")
660
661 __ASM_EMIT("mov %0, %1")
662 __ASM_EMIT("and %2, %1")
663 __ASM_EMIT("shr $4, %0")
664 __ASM_EMIT("shl $4, %1")
665 __ASM_EMIT("and %2, %0")
666 __ASM_EMIT("or %1, %0")
667
668 __ASM_EMIT("mov %0, %1")
669 __ASM_EMIT("and %3, %1")
670 __ASM_EMIT("shr $2, %0")
671 __ASM_EMIT("and %3, %0")
672 __ASM_EMIT("lea (%0,%1,4), %0")
673
674 __ASM_EMIT("mov %0, %1")
675 __ASM_EMIT("and %4, %1")
676 __ASM_EMIT("shr $1, %0")
677 __ASM_EMIT("and %4, %0")
678 __ASM_EMIT("lea (%0,%1,2), %0")
679
680 : "+r"(v), "=&r"(tmp)
681 :
682 "r"(0x0f0f0f0f0f0f0f0fULL),
683 "r"(0x3333333333333333ULL),
684 "r"(0x5555555555555555ULL)
685 : "cc"
686 );
687
688 return v;
689 }
690
reverse_bits(int64_t v)691 inline int64_t __lsp_forced_inline reverse_bits(int64_t v)
692 {
693 register uint64_t tmp;
694
695 ARCH_X86_ASM (
696 __ASM_EMIT("bswap %0")
697
698 __ASM_EMIT("mov %0, %1")
699 __ASM_EMIT("and %2, %1")
700 __ASM_EMIT("shr $4, %0")
701 __ASM_EMIT("shl $4, %1")
702 __ASM_EMIT("and %2, %0")
703 __ASM_EMIT("or %1, %0")
704
705 __ASM_EMIT("mov %0, %1")
706 __ASM_EMIT("and %3, %1")
707 __ASM_EMIT("shr $2, %0")
708 __ASM_EMIT("and %3, %0")
709 __ASM_EMIT("lea (%0,%1,4), %0")
710
711 __ASM_EMIT("mov %0, %1")
712 __ASM_EMIT("and %4, %1")
713 __ASM_EMIT("shr $1, %0")
714 __ASM_EMIT("and %4, %0")
715 __ASM_EMIT("lea (%0,%1,2), %0")
716
717 : "+r"(v), "=&r"(tmp)
718 :
719 "r"(0x0f0f0f0f0f0f0f0fULL),
720 "r"(0x3333333333333333ULL),
721 "r"(0x5555555555555555ULL)
722 : "cc"
723 );
724
725 return v;
726 }
727
reverse_bits(uint64_t v,size_t count)728 inline uint64_t __lsp_forced_inline reverse_bits(uint64_t v, size_t count)
729 {
730 register uint64_t tmp;
731
732 ARCH_X86_ASM (
733 __ASM_EMIT("bswap %0")
734
735 __ASM_EMIT("mov %0, %1")
736 __ASM_EMIT("and %2, %1")
737 __ASM_EMIT("shr $4, %0")
738 __ASM_EMIT("shl $4, %1")
739 __ASM_EMIT("and %2, %0")
740 __ASM_EMIT("or %1, %0")
741
742 __ASM_EMIT("mov %0, %1")
743 __ASM_EMIT("and %3, %1")
744 __ASM_EMIT("shr $2, %0")
745 __ASM_EMIT("and %3, %0")
746 __ASM_EMIT("lea (%0,%1,4), %0")
747
748 __ASM_EMIT("mov %0, %1")
749 __ASM_EMIT("and %4, %1")
750 __ASM_EMIT("shr $1, %0")
751 __ASM_EMIT("and %4, %0")
752 __ASM_EMIT("lea (%0,%1,2), %0")
753
754 __ASM_EMIT("shr %%cl, %0")
755
756 : "+r"(v), "=&r"(tmp)
757 :
758 "r"(0x0f0f0f0f0f0f0f0fULL),
759 "r"(0x3333333333333333ULL),
760 "r"(0x5555555555555555ULL),
761 "c"(64-count)
762 : "cc"
763 );
764
765 return v;
766 }
767
reverse_bits(int64_t v,size_t count)768 inline int64_t __lsp_forced_inline reverse_bits(int64_t v, size_t count)
769 {
770 register uint64_t tmp;
771
772 ARCH_X86_ASM (
773 __ASM_EMIT("bswap %0")
774
775 __ASM_EMIT("mov %0, %1")
776 __ASM_EMIT("and %2, %1")
777 __ASM_EMIT("shr $4, %0")
778 __ASM_EMIT("shl $4, %1")
779 __ASM_EMIT("and %2, %0")
780 __ASM_EMIT("or %1, %0")
781
782 __ASM_EMIT("mov %0, %1")
783 __ASM_EMIT("and %3, %1")
784 __ASM_EMIT("shr $2, %0")
785 __ASM_EMIT("and %3, %0")
786 __ASM_EMIT("lea (%0,%1,4), %0")
787
788 __ASM_EMIT("mov %0, %1")
789 __ASM_EMIT("and %4, %1")
790 __ASM_EMIT("shr $1, %0")
791 __ASM_EMIT("and %4, %0")
792 __ASM_EMIT("lea (%0,%1,2), %0")
793
794 __ASM_EMIT("shr %%cl, %0")
795
796 : "+r"(v), "=&r"(tmp)
797 :
798 "r"(0x0f0f0f0f0f0f0f0fULL),
799 "r"(0x3333333333333333ULL),
800 "r"(0x5555555555555555ULL),
801 "c"(64-count)
802 : "cc"
803 );
804
805 return v;
806 }
807
808 #endif /* ARCH_I386 */
809
810
int_log2(uint8_t v)811 inline int __lsp_forced_inline int_log2(uint8_t v)
812 {
813 uint32_t res = v, tmp;
814
815 ARCH_X86_ASM (
816 __ASM_EMIT("xor %[tmp], %[tmp]")
817 __ASM_EMIT("bsr %[res], %[res]")
818 __ASM_EMIT("cmovz %[tmp], %[res]")
819 : [res] "+r" (res), [tmp] "=&r" (tmp)
820 :
821 : "cc"
822 );
823 return res;
824 }
825
int_log2(int8_t v)826 inline int __lsp_forced_inline int_log2(int8_t v)
827 {
828 uint32_t res = uint8_t(v), tmp;
829
830 ARCH_X86_ASM (
831 __ASM_EMIT("xor %[tmp], %[tmp]")
832 __ASM_EMIT("bsr %[res], %[res]")
833 __ASM_EMIT("cmovz %[tmp], %[res]")
834 : [res] "+r" (res), [tmp] "=&r" (tmp)
835 :
836 : "cc"
837 );
838 return res;
839 }
840
int_log2(uint16_t v)841 inline int __lsp_forced_inline int_log2(uint16_t v)
842 {
843 uint32_t res = v, tmp;
844
845 ARCH_X86_ASM (
846 __ASM_EMIT("xor %[tmp], %[tmp]")
847 __ASM_EMIT("bsr %[res], %[res]")
848 __ASM_EMIT("cmovz %[tmp], %[res]")
849 : [res] "+r" (res), [tmp] "=&r" (tmp)
850 :
851 : "cc"
852 );
853 return res;
854 }
855
int_log2(int16_t v)856 inline int __lsp_forced_inline int_log2(int16_t v)
857 {
858 uint32_t res = uint16_t(v), tmp;
859
860 ARCH_X86_ASM (
861 __ASM_EMIT("xor %[tmp], %[tmp]")
862 __ASM_EMIT("bsr %[res], %[res]")
863 __ASM_EMIT("cmovz %[tmp], %[res]")
864 : [res] "+r" (res), [tmp] "=&r" (tmp)
865 :
866 : "cc"
867 );
868 return res;
869 }
870
int_log2(uint32_t v)871 inline int __lsp_forced_inline int_log2(uint32_t v)
872 {
873 uint32_t tmp;
874
875 ARCH_X86_ASM (
876 __ASM_EMIT("xor %[tmp], %[tmp]")
877 __ASM_EMIT("bsr %[res], %[res]")
878 __ASM_EMIT("cmovz %[tmp], %[res]")
879 : [res] "+r" (v), [tmp] "=&r" (tmp)
880 :
881 : "cc"
882 );
883 return v;
884 }
885
int_log2(int32_t v)886 inline int __lsp_forced_inline int_log2(int32_t v)
887 {
888 uint32_t tmp;
889
890 ARCH_X86_ASM (
891 __ASM_EMIT("xor %[tmp], %[tmp]")
892 __ASM_EMIT("bsr %[res], %[res]")
893 __ASM_EMIT("cmovz %[tmp], %[res]")
894 : [res] "+r" (v), [tmp] "=&r" (tmp)
895 :
896 : "cc"
897 );
898 return v;
899 }
900
901 #ifdef ARCH_X86_64
int_log2(uint64_t v)902 inline int __lsp_forced_inline int_log2(uint64_t v)
903 {
904 uint64_t tmp;
905
906 ARCH_X86_ASM (
907 __ASM_EMIT("xor %[tmp], %[tmp]")
908 __ASM_EMIT("bsr %[res], %[res]")
909 __ASM_EMIT("cmovz %[tmp], %[res]")
910 : [res] "+r" (v), [tmp] "=&r" (tmp)
911 :
912 : "cc"
913 );
914 return int(v);
915 }
916
int_log2(int64_t v)917 inline int __lsp_forced_inline int_log2(int64_t v)
918 {
919 uint64_t tmp;
920
921 ARCH_X86_ASM (
922 __ASM_EMIT("xor %[tmp], %[tmp]")
923 __ASM_EMIT("bsr %[res], %[res]")
924 __ASM_EMIT("cmovz %[tmp], %[res]")
925 : [res] "+r" (v), [tmp] "=&r" (tmp)
926 :
927 : "cc"
928 );
929 return int(v);
930 }
931 #else
int_log2(uint64_t v)932 inline int __lsp_forced_inline int_log2(uint64_t v)
933 {
934 ARCH_X86_ASM (
935 __ASM_EMIT("test %%edx, %%edx")
936 __ASM_EMIT("jz 2f")
937 __ASM_EMIT("mov %%edx, %%eax")
938 __ASM_EMIT("xor %%edx, %%edx")
939 __ASM_EMIT("bsr %%eax, %%eax")
940 __ASM_EMIT("cmovz %%edx, %%eax")
941 __ASM_EMIT("add $32, %%eax")
942 __ASM_EMIT("jmp 4f")
943
944 __ASM_EMIT("2:")
945 __ASM_EMIT("xor %%edx, %%edx")
946 __ASM_EMIT("bsr %%eax, %%eax")
947 __ASM_EMIT("cmovz %%edx, %%eax")
948
949 __ASM_EMIT("4:")
950
951 : [v] "+A" (v)
952 :
953 : "cc"
954 );
955 return int(v);
956 }
957
int_log2(int64_t v)958 inline int __lsp_forced_inline int_log2(int64_t v)
959 {
960 ARCH_X86_ASM (
961 __ASM_EMIT("test %%edx, %%edx")
962 __ASM_EMIT("jz 2f")
963 __ASM_EMIT("mov %%edx, %%eax")
964 __ASM_EMIT("xor %%edx, %%edx")
965 __ASM_EMIT("bsr %%eax, %%eax")
966 __ASM_EMIT("cmovz %%edx, %%eax")
967 __ASM_EMIT("add $32, %%eax")
968 __ASM_EMIT("jmp 4f")
969
970 __ASM_EMIT("2:")
971 __ASM_EMIT("xor %%edx, %%edx")
972 __ASM_EMIT("bsr %%eax, %%eax")
973 __ASM_EMIT("cmovz %%edx, %%eax")
974
975 __ASM_EMIT("4:")
976
977 : [v] "+A" (v)
978 :
979 : "cc"
980 );
981 return int(v);
982 }
983 #endif /* ARCH_X86_64 */
984
985 #endif /* DSP_ARCH_X86_BITS_H_ */
986