* implemented remaing avg_ pixel functions (these are not used offen)
[ffmpeg.git] / libavcodec / i386 / dsputil_mmx_rnd.h
1 /*
2  * DSP utils mmx functions are compiled twice for rnd/no_rnd
3  * Copyright (c) 2000, 2001 Fabrice Bellard.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  * MMX optimization by Nick Kurshev <nickols_k@mail.ru>
20  * mostly rewritten by Michael Niedermayer <michaelni@gmx.at>
21  * and improved by Zdenek Kabelac <kabi@users.sf.net>
22  */
23
24 // put_pixels
25 static void DEF(put, pixels_x2)(UINT8 *block, const UINT8 *pixels, int line_size, int h)
26 {
27     MOVQ_BFE(mm6);
28     __asm __volatile(
29         "lea    (%3, %3), %%eax         \n\t"
30         ".balign 8                      \n\t"
31         "1:                             \n\t"
32         "movq   (%1), %%mm0             \n\t"
33         "movq   1(%1), %%mm1            \n\t"
34         "movq   (%1, %3), %%mm2         \n\t"
35         "movq   1(%1, %3), %%mm3        \n\t"
36         PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
37         "movq   %%mm4, (%2)             \n\t"
38         "movq   %%mm5, (%2, %3)         \n\t"
39         "addl   %%eax, %1               \n\t"
40         "addl   %%eax, %2               \n\t"
41         "movq   (%1), %%mm0             \n\t"
42         "movq   1(%1), %%mm1            \n\t"
43         "movq   (%1, %3), %%mm2         \n\t"
44         "movq   1(%1, %3), %%mm3        \n\t"
45         PAVGBP(%%mm0, %%mm1, %%mm4,   %%mm2, %%mm3, %%mm5)
46         "movq   %%mm4, (%2)             \n\t"
47         "movq   %%mm5, (%2, %3)         \n\t"
48         "addl   %%eax, %1               \n\t"
49         "addl   %%eax, %2               \n\t"
50         "subl   $4, %0                  \n\t"
51         "jnz    1b                      \n\t"
52         :"+g"(h), "+S"(pixels), "+D"(block)
53         :"r"(line_size)
54         :"eax", "memory");
55 }
56
57 static void DEF(put, pixels_y2)(UINT8 *block, const UINT8 *pixels, int line_size, int h)
58 {
59     MOVQ_BFE(mm6);
60     __asm __volatile(
61         "lea (%3, %3), %%eax            \n\t"
62         "movq (%1), %%mm0               \n\t"
63         ".balign 8                      \n\t"
64         "1:                             \n\t"
65         "movq   (%1, %3), %%mm1         \n\t"
66         "movq   (%1, %%eax),%%mm2       \n\t"
67         PAVGBP(%%mm1, %%mm0, %%mm4,   %%mm2, %%mm1, %%mm5)
68         "movq   %%mm4, (%2)             \n\t"
69         "movq   %%mm5, (%2, %3)         \n\t"
70         "addl   %%eax, %1               \n\t"
71         "addl   %%eax, %2               \n\t"
72         "movq   (%1, %3), %%mm1         \n\t"
73         "movq   (%1, %%eax),%%mm0       \n\t"
74         PAVGBP(%%mm1, %%mm2, %%mm4,   %%mm0, %%mm1, %%mm5)
75         "movq   %%mm4, (%2)             \n\t"
76         "movq   %%mm5, (%2, %3)         \n\t"
77         "addl   %%eax, %1               \n\t"
78         "addl   %%eax, %2               \n\t"
79         "subl   $4, %0                  \n\t"
80         "jnz    1b                      \n\t"
81         :"+g"(h), "+S"(pixels), "+D"(block)
82         :"r"(line_size)
83         :"eax", "memory");
84 }
85
86 static void DEF(put, pixels_xy2)(UINT8 *block, const UINT8 *pixels, int line_size, int h)
87 {
88     MOVQ_ZERO(mm7);
89     SET_RND(mm6); // =2 for rnd  and  =1 for no_rnd version
90     __asm __volatile(
91         "movq   (%1), %%mm0             \n\t"
92         "movq   1(%1), %%mm4            \n\t"
93         "movq   %%mm0, %%mm1            \n\t"
94         "movq   %%mm4, %%mm5            \n\t"
95         "punpcklbw %%mm7, %%mm0         \n\t"
96         "punpcklbw %%mm7, %%mm4         \n\t"
97         "punpckhbw %%mm7, %%mm1         \n\t"
98         "punpckhbw %%mm7, %%mm5         \n\t"
99         "paddusw %%mm0, %%mm4           \n\t"
100         "paddusw %%mm1, %%mm5           \n\t"
101         "xorl   %%eax, %%eax            \n\t"
102         "addl   %3, %1                  \n\t"
103         ".balign 8                      \n\t"
104         "1:                             \n\t"
105         "movq   (%1, %%eax), %%mm0      \n\t"
106         "movq   1(%1, %%eax), %%mm2     \n\t"
107         "movq   %%mm0, %%mm1            \n\t"
108         "movq   %%mm2, %%mm3            \n\t"
109         "punpcklbw %%mm7, %%mm0         \n\t"
110         "punpcklbw %%mm7, %%mm2         \n\t"
111         "punpckhbw %%mm7, %%mm1         \n\t"
112         "punpckhbw %%mm7, %%mm3         \n\t"
113         "paddusw %%mm2, %%mm0           \n\t"
114         "paddusw %%mm3, %%mm1           \n\t"
115         "paddusw %%mm6, %%mm4           \n\t"
116         "paddusw %%mm6, %%mm5           \n\t"
117         "paddusw %%mm0, %%mm4           \n\t"
118         "paddusw %%mm1, %%mm5           \n\t"
119         "psrlw  $2, %%mm4               \n\t"
120         "psrlw  $2, %%mm5               \n\t"
121         "packuswb  %%mm5, %%mm4         \n\t"
122         "movq   %%mm4, (%2, %%eax)      \n\t"
123         "addl   %3, %%eax               \n\t"
124
125         "movq   (%1, %%eax), %%mm2      \n\t" // 0 <-> 2   1 <-> 3
126         "movq   1(%1, %%eax), %%mm4     \n\t"
127         "movq   %%mm2, %%mm3            \n\t"
128         "movq   %%mm4, %%mm5            \n\t"
129         "punpcklbw %%mm7, %%mm2         \n\t"
130         "punpcklbw %%mm7, %%mm4         \n\t"
131         "punpckhbw %%mm7, %%mm3         \n\t"
132         "punpckhbw %%mm7, %%mm5         \n\t"
133         "paddusw %%mm2, %%mm4           \n\t"
134         "paddusw %%mm3, %%mm5           \n\t"
135         "paddusw %%mm6, %%mm0           \n\t"
136         "paddusw %%mm6, %%mm1           \n\t"
137         "paddusw %%mm4, %%mm0           \n\t"
138         "paddusw %%mm5, %%mm1           \n\t"
139         "psrlw  $2, %%mm0               \n\t"
140         "psrlw  $2, %%mm1               \n\t"
141         "packuswb  %%mm1, %%mm0         \n\t"
142         "movq   %%mm0, (%2, %%eax)      \n\t"
143         "addl   %3, %%eax               \n\t"
144
145         "subl   $2, %0                  \n\t"
146         "jnz    1b                      \n\t"
147         :"+g"(h), "+S"(pixels)
148         :"D"(block), "r"(line_size)
149         :"eax", "memory");
150 }
151
152 // avg_pixels
153 // in case more speed is needed - unroling would certainly help
154 static void DEF(avg, pixels)(UINT8 *block, const UINT8 *pixels, int line_size, int h)
155 {
156     MOVQ_BFE(mm6);
157     JUMPALIGN();
158     do {
159         __asm __volatile(
160              "movq  %0, %%mm0           \n\t"
161              "movq  %1, %%mm1           \n\t"
162              PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
163              "movq  %%mm2, %0           \n\t"
164              :"+m"(*block)
165              :"m"(*pixels)
166              :"memory");
167         pixels += line_size;
168         block += line_size;
169     }
170     while (--h);
171 }
172
173 static void DEF(avg, pixels_x2)(UINT8 *block, const UINT8 *pixels, int line_size, int h)
174 {
175     MOVQ_BFE(mm6);
176     JUMPALIGN();
177     do {
178         __asm __volatile(
179             "movq  %1, %%mm0            \n\t"
180             "movq  1%1, %%mm1           \n\t"
181             "movq  %0, %%mm3            \n\t"
182             PAVGB(%%mm0, %%mm1, %%mm2, %%mm6)
183             PAVGB(%%mm3, %%mm2, %%mm0, %%mm6)
184             "movq  %%mm0, %0            \n\t"
185             :"+m"(*block)
186             :"m"(*pixels)
187             :"memory");
188         pixels += line_size;
189         block += line_size;
190     } while (--h);
191 }
192
193 static void DEF(avg, pixels_y2)(UINT8 *block, const UINT8 *pixels, int line_size, int h)
194 {
195     MOVQ_BFE(mm6);
196     __asm __volatile(
197         "lea    (%3, %3), %%eax         \n\t"
198         "movq   (%1), %%mm0             \n\t"
199         ".balign 8                      \n\t"
200         "1:                             \n\t"
201         "movq   (%1, %3), %%mm1         \n\t"
202         "movq   (%1, %%eax), %%mm2      \n\t"
203         PAVGBP(%%mm1, %%mm0, %%mm4,   %%mm2, %%mm1, %%mm5)
204         "movq   (%2), %%mm3             \n\t"
205         PAVGB(%%mm3, %%mm4, %%mm0, %%mm6)
206         "movq   (%2, %3), %%mm3         \n\t"
207         PAVGB(%%mm3, %%mm5, %%mm1, %%mm6)
208         "movq   %%mm0, (%2)             \n\t"
209         "movq   %%mm1, (%2, %3)         \n\t"
210         "addl   %%eax, %1               \n\t"
211         "addl   %%eax, %2               \n\t"
212
213         "movq   (%1, %3), %%mm1         \n\t"
214         "movq   (%1, %%eax), %%mm0      \n\t"
215         PAVGBP(%%mm1, %%mm2, %%mm4,   %%mm0, %%mm1, %%mm5)
216         "movq   (%2), %%mm3             \n\t"
217         PAVGB(%%mm3, %%mm4, %%mm0, %%mm6)
218         "movq   (%2, %3), %%mm3         \n\t"
219         PAVGB(%%mm3, %%mm5, %%mm1, %%mm6)
220         "movq   %%mm0, (%2)             \n\t"
221         "movq   %%mm1, (%2, %3)         \n\t"
222         "addl   %%eax, %1               \n\t"
223         "addl   %%eax, %2               \n\t"
224
225         "subl   $4, %0                  \n\t"
226         "jnz    1b                      \n\t"
227         :"+g"(h), "+S"(pixels), "+D"(block)
228         :"r"(line_size)
229         :"eax", "memory");
230 }
231
232 // this routine is 'slightly' suboptimal but mostly unused
233 static void DEF(avg, pixels_xy2)(UINT8 *block, const UINT8 *pixels, int line_size, int h)
234 {
235     MOVQ_ZERO(mm7);
236     SET_RND(mm6); // =2 for rnd  and  =1 for no_rnd version
237     __asm __volatile(
238         "movq   (%1), %%mm0             \n\t"
239         "movq   1(%1), %%mm4            \n\t"
240         "movq   %%mm0, %%mm1            \n\t"
241         "movq   %%mm4, %%mm5            \n\t"
242         "punpcklbw %%mm7, %%mm0         \n\t"
243         "punpcklbw %%mm7, %%mm4         \n\t"
244         "punpckhbw %%mm7, %%mm1         \n\t"
245         "punpckhbw %%mm7, %%mm5         \n\t"
246         "paddusw %%mm0, %%mm4           \n\t"
247         "paddusw %%mm1, %%mm5           \n\t"
248         "xorl   %%eax, %%eax            \n\t"
249         "addl   %3, %1                  \n\t"
250         ".balign 8                      \n\t"
251         "1:                             \n\t"
252         "movq   (%1, %%eax), %%mm0      \n\t"
253         "movq   1(%1, %%eax), %%mm2     \n\t"
254         "movq   %%mm0, %%mm1            \n\t"
255         "movq   %%mm2, %%mm3            \n\t"
256         "punpcklbw %%mm7, %%mm0         \n\t"
257         "punpcklbw %%mm7, %%mm2         \n\t"
258         "punpckhbw %%mm7, %%mm1         \n\t"
259         "punpckhbw %%mm7, %%mm3         \n\t"
260         "paddusw %%mm2, %%mm0           \n\t"
261         "paddusw %%mm3, %%mm1           \n\t"
262         "paddusw %%mm6, %%mm4           \n\t"
263         "paddusw %%mm6, %%mm5           \n\t"
264         "paddusw %%mm0, %%mm4           \n\t"
265         "paddusw %%mm1, %%mm5           \n\t"
266         "psrlw  $2, %%mm4               \n\t"
267         "psrlw  $2, %%mm5               \n\t"
268                 "movq   (%2, %%eax), %%mm3      \n\t"
269         "packuswb  %%mm5, %%mm4         \n\t"
270                 "pcmpeqd %%mm2, %%mm2   \n\t"
271                 "paddb %%mm2, %%mm2     \n\t"
272                 PAVGB(%%mm3, %%mm4, %%mm5, %%mm2)
273                 "movq   %%mm5, (%2, %%eax)      \n\t"
274         "addl   %3, %%eax               \n\t"
275
276         "movq   (%1, %%eax), %%mm2      \n\t" // 0 <-> 2   1 <-> 3
277         "movq   1(%1, %%eax), %%mm4     \n\t"
278         "movq   %%mm2, %%mm3            \n\t"
279         "movq   %%mm4, %%mm5            \n\t"
280         "punpcklbw %%mm7, %%mm2         \n\t"
281         "punpcklbw %%mm7, %%mm4         \n\t"
282         "punpckhbw %%mm7, %%mm3         \n\t"
283         "punpckhbw %%mm7, %%mm5         \n\t"
284         "paddusw %%mm2, %%mm4           \n\t"
285         "paddusw %%mm3, %%mm5           \n\t"
286         "paddusw %%mm6, %%mm0           \n\t"
287         "paddusw %%mm6, %%mm1           \n\t"
288         "paddusw %%mm4, %%mm0           \n\t"
289         "paddusw %%mm5, %%mm1           \n\t"
290         "psrlw  $2, %%mm0               \n\t"
291         "psrlw  $2, %%mm1               \n\t"
292                 "movq   (%2, %%eax), %%mm3      \n\t"
293         "packuswb  %%mm1, %%mm0         \n\t"
294                 "pcmpeqd %%mm2, %%mm2   \n\t"
295                 "paddb %%mm2, %%mm2     \n\t"
296                 PAVGB(%%mm3, %%mm0, %%mm1, %%mm2)
297                 "movq   %%mm1, (%2, %%eax)      \n\t"
298         "addl   %3, %%eax               \n\t"
299
300         "subl   $2, %0                  \n\t"
301         "jnz    1b                      \n\t"
302         :"+g"(h), "+S"(pixels)
303         :"D"(block), "r"(line_size)
304         :"eax", "memory");
305 }