Git init
[profile/ivi/liboil.git] / liboil / i386_amd64 / swab.c
1 /*
2  * LIBOIL - Library of Optimized Inner Loops
3  * Copyright (c) 2005 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
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31
32 #include <liboil/liboilfunction.h>
33 #include <liboil/liboilclasses.h>
34
35 static void
36 swab_u32_i386 (uint32_t *dest, uint32_t *src, int n)
37 {
38   asm volatile ("\n"
39       "1:\n"
40       "  movl 0(%1), %%eax\n"
41       "  bswap %%eax\n"
42       "  movl %%eax, 0(%0)\n"
43       "  add $4, %0\n"
44       "  add $4, %1\n"
45       "  decl %2\n"
46       "  jnz 1b\n"
47       : "+r" (dest), "+r" (src), "+r" (n)
48       :
49       : "eax", "memory");
50 }
51 OIL_DEFINE_IMPL (swab_u32_i386, swab_u32);
52
53 static void
54 swab_u32_i386_unroll2 (uint32_t *dest, uint32_t *src, int n)
55 {
56   asm volatile ("\n"
57       "  test $1, %2\n"
58       "  jz 1f\n"
59       "  movl 0(%1), %%eax\n"
60       "  bswap %%eax\n"
61       "  movl %%eax, 0(%0)\n"
62       "  add $4, %0\n"
63       "  add $4, %1\n"
64       "  decl %2\n"
65       "  jz 2f\n"
66       "1:\n"
67       "  movl 0(%1), %%eax\n"
68       "  movl 4(%1), %%ecx\n"
69       "  bswap %%eax\n"
70       "  bswap %%ecx\n"
71       "  movl %%eax, 0(%0)\n"
72       "  movl %%ecx, 4(%0)\n"
73       "  add $8, %0\n"
74       "  add $8, %1\n"
75       "  sub $2, %2\n"
76       "  jnz 1b\n"
77       "2:\n"
78       : "+r" (dest), "+r" (src), "+r" (n)
79       :
80       : "eax", "ecx", "memory");
81 }
82 OIL_DEFINE_IMPL (swab_u32_i386_unroll2, swab_u32);
83
84 static void
85 swab_u32_i386_unroll4 (uint32_t *dest, uint32_t *src, int n)
86 {
87   asm volatile ("\n"
88       "  jmp 2f\n"
89       "1:\n"
90       "  movl 0(%1), %%eax\n"
91       "  bswap %%eax\n"
92       "  movl %%eax, 0(%0)\n"
93       "  add $4, %0\n"
94       "  add $4, %1\n"
95       "  decl %2\n"
96       "2:\n"
97       "  test $3, %2\n"
98       "  jnz 1b\n"
99       "  test %2, %2\n"
100       "  jz 4f\n"
101       "3:\n"
102       "  movl 0(%1), %%eax\n"
103       "  movl 4(%1), %%ecx\n"
104       "  bswap %%eax\n"
105       "  bswap %%ecx\n"
106       "  movl %%eax, 0(%0)\n"
107       "  movl %%ecx, 4(%0)\n"
108       "  movl 8(%1), %%eax\n"
109       "  movl 12(%1), %%ecx\n"
110       "  bswap %%eax\n"
111       "  bswap %%ecx\n"
112       "  movl %%eax, 8(%0)\n"
113       "  movl %%ecx, 12(%0)\n"
114       "  add $16, %0\n"
115       "  add $16, %1\n"
116       "  sub $4, %2\n"
117       "  jnz 3b\n"
118       "4:\n"
119       : "+r" (dest), "+r" (src), "+r" (n)
120       :
121       : "eax", "ecx", "memory");
122 }
123 OIL_DEFINE_IMPL (swab_u32_i386_unroll4, swab_u32);
124
125
126
127 /*
128  * This could be improved by using aligned stores
129  */
130 static void
131 swab_u16_mmx (uint16_t *dest, uint16_t *src, int n)
132 {
133   asm volatile ("\n"
134       "  jmp 2f\n"
135       "1:\n"
136       "  movw 0(%1), %%ax\n"
137       "  xchg %%al, %%ah\n"
138       "  movw %%ax, 0(%0)\n"
139       "  add $2, %0\n"
140       "  add $2, %1\n"
141       "  decl %2\n"
142       "2:\n"
143       "  test $3, %2\n"
144       "  jnz 1b\n"
145       "  test %2, %2\n"
146       "  jz 4f\n"
147       "3:\n"
148       "  movq 0(%1), %%mm0\n"
149       "  movq 0(%1), %%mm1\n"
150       "  psllw $8, %%mm0\n"
151       "  psrlw $8, %%mm1\n"
152       "  por %%mm0, %%mm1\n"
153       "  movq %%mm1, 0(%0)\n"
154       "  add $8, %0\n"
155       "  add $8, %1\n"
156       "  sub $4, %2\n"
157       "  jnz 3b\n"
158       "  emms\n"
159       "4:\n"
160       : "+r" (dest), "+r" (src), "+r" (n)
161       :
162       : "eax", "memory");
163 }
164 OIL_DEFINE_IMPL_FULL (swab_u16_mmx, swab_u16, OIL_IMPL_FLAG_MMX);
165
166 static void
167 swab_u16_mmx_unroll2 (uint16_t *dest, uint16_t *src, int n)
168 {
169   asm volatile ("\n"
170       "  jmp 2f\n"
171       "1:\n"
172       "  movw 0(%1), %%ax\n"
173       "  xchg %%al, %%ah\n"
174       "  movw %%ax, 0(%0)\n"
175       "  add $2, %0\n"
176       "  add $2, %1\n"
177       "  decl %2\n"
178       "2:\n"
179       "  test $7, %2\n"
180       "  jnz 1b\n"
181       "  test %2, %2\n"
182       "  jz 4f\n"
183       "3:\n"
184       "  movq 0(%1), %%mm0\n"
185       "  movq 0(%1), %%mm1\n"
186       "   movq 8(%1), %%mm2\n"
187       "  psllw $8, %%mm0\n"
188       "   movq 8(%1), %%mm3\n"
189       "  psrlw $8, %%mm1\n"
190       "   psllw $8, %%mm2\n"
191       "  por %%mm0, %%mm1\n"
192       "   psrlw $8, %%mm3\n"
193       "  movq %%mm1, 0(%0)\n"
194       "   por %%mm2, %%mm3\n"
195       "   movq %%mm3, 8(%0)\n"
196       "  add $16, %0\n"
197       "  add $16, %1\n"
198       "  sub $8, %2\n"
199       "  jnz 3b\n"
200       "  emms\n"
201       "4:\n"
202       : "+r" (dest), "+r" (src), "+r" (n)
203       :
204       : "eax", "memory");
205 }
206 OIL_DEFINE_IMPL_FULL (swab_u16_mmx_unroll2, swab_u16, OIL_IMPL_FLAG_MMX);
207
208 /* 10 instructions to swab 2 words?  not likely */
209 static void
210 swab_u32_mmx (uint16_t *dest, uint16_t *src, int n)
211 {
212   asm volatile ("\n"
213       "  jmp 2f\n"
214       "1:\n"
215       "  movl 0(%1), %%eax\n"
216       "  bswap %%eax\n"
217       "  movl %%eax, 0(%0)\n"
218       "  add $4, %0\n"
219       "  add $4, %1\n"
220       "  decl %2\n"
221       "2:\n"
222       "  test $1, %2\n"
223       "  jnz 1b\n"
224       "  test %2, %2\n"
225       "  jz 4f\n"
226       "3:\n"
227       "  movq 0(%1), %%mm0\n"
228       "  movq 0(%1), %%mm1\n"
229       "  psllw $8, %%mm0\n"
230       "  psrlw $8, %%mm1\n"
231       "  por %%mm0, %%mm1\n"
232       "  movq %%mm1, %%mm0\n"
233       "  pslld $16, %%mm0\n"
234       "  psrld $16, %%mm1\n"
235       "  por %%mm0, %%mm1\n"
236       "  movq %%mm1, 0(%0)\n"
237       "  add $8, %0\n"
238       "  add $8, %1\n"
239       "  sub $2, %2\n"
240       "  jnz 3b\n"
241       "  emms\n"
242       "4:\n"
243       : "+r" (dest), "+r" (src), "+r" (n)
244       :
245       : "eax", "memory");
246 }
247 OIL_DEFINE_IMPL_FULL (swab_u32_mmx, swab_u32, OIL_IMPL_FLAG_MMX);
248
249 static void
250 swab_u16_sse2 (uint16_t *dest, uint16_t *src, int n)
251 {
252   asm volatile ("\n"
253       "  jmp 2f\n"
254       "1:\n"
255       "  movw 0(%1), %%ax\n"
256       "  xchg %%al, %%ah\n"
257       "  movw %%ax, 0(%0)\n"
258       "  add $2, %0\n"
259       "  add $2, %1\n"
260       "  decl %2\n"
261       "2:\n"
262       "  test $7, %2\n"
263       "  jnz 1b\n"
264       "  test %2, %2\n"
265       "  jz 4f\n"
266       "3:\n"
267       "  movdqu 0(%1), %%xmm0\n"
268       "  movdqu 0(%1), %%xmm1\n"
269       "  psllw $8, %%xmm0\n"
270       "  psrlw $8, %%xmm1\n"
271       "  por %%xmm0, %%xmm1\n"
272       "  movdqu %%xmm1, 0(%0)\n"
273       "  add $16, %0\n"
274       "  add $16, %1\n"
275       "  sub $8, %2\n"
276       "  jnz 3b\n"
277       "4:\n"
278       : "+r" (dest), "+r" (src), "+r" (n)
279       :
280       : "eax", "memory");
281 }
282 OIL_DEFINE_IMPL_FULL (swab_u16_sse2, swab_u16, OIL_IMPL_FLAG_SSE2);
283
284 static void
285 swab_u32_sse2 (uint16_t *dest, uint16_t *src, int n)
286 {
287   asm volatile ("\n"
288       "  jmp 2f\n"
289       "1:\n"
290       "  movl 0(%1), %%eax\n"
291       "  bswap %%eax\n"
292       "  movl %%eax, 0(%0)\n"
293       "  add $4, %0\n"
294       "  add $4, %1\n"
295       "  decl %2\n"
296       "2:\n"
297       "  test $3, %2\n"
298       "  jnz 1b\n"
299       "  test %2, %2\n"
300       "  jz 4f\n"
301       "3:\n"
302       "  movdqu 0(%1), %%xmm0\n"
303       "  movdqu 0(%1), %%xmm1\n"
304       "  psllw $8, %%xmm0\n"
305       "  psrlw $8, %%xmm1\n"
306       "  por %%xmm0, %%xmm1\n"
307       "  movdqu %%xmm1, %%xmm0\n"
308       "  pslld $16, %%xmm0\n"
309       "  psrld $16, %%xmm1\n"
310       "  por %%xmm0, %%xmm1\n"
311       "  movdqu %%xmm1, 0(%0)\n"
312       "  add $16, %0\n"
313       "  add $16, %1\n"
314       "  sub $4, %2\n"
315       "  jnz 3b\n"
316       "4:\n"
317       : "+r" (dest), "+r" (src), "+r" (n)
318       :
319       : "eax", "memory");
320 }
321 OIL_DEFINE_IMPL_FULL (swab_u32_sse2, swab_u32, OIL_IMPL_FLAG_SSE2);
322