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