]> rtime.felk.cvut.cz Git - frescor/ffmpeg.git/blob - libavcodec/i386/vp3dsp_sse2.c
Declare ff_vp3_idct_data to be uint16_t
[frescor/ffmpeg.git] / libavcodec / i386 / vp3dsp_sse2.c
1 /*
2  * Copyright (C) 2004 the ffmpeg project
3  *
4  * This file is part of FFmpeg.
5  *
6  * FFmpeg 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.1 of the License, or (at your option) any later version.
10  *
11  * FFmpeg 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 FFmpeg; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /**
22  * @file vp3dsp_sse2.c
23  * SSE2-optimized functions cribbed from the original VP3 source code.
24  */
25
26 #include "libavcodec/dsputil.h"
27 #include "dsputil_mmx.h"
28 #include "mmx.h"
29
30 DECLARE_ALIGNED_16(const uint16_t, ff_vp3_idct_data[7 * 8]) =
31 {
32     64277,64277,64277,64277,64277,64277,64277,64277,
33     60547,60547,60547,60547,60547,60547,60547,60547,
34     54491,54491,54491,54491,54491,54491,54491,54491,
35     46341,46341,46341,46341,46341,46341,46341,46341,
36     36410,36410,36410,36410,36410,36410,36410,36410,
37     25080,25080,25080,25080,25080,25080,25080,25080,
38     12785,12785,12785,12785,12785,12785,12785,12785
39 };
40
41
42 #define SSE2_Column_IDCT() {        \
43     \
44     movdqa_m2r(*I(3), xmm2);     /* xmm2 = i3 */ \
45     movdqa_m2r(*C(3), xmm6);     /* xmm6 = c3 */ \
46     \
47     movdqa_r2r(xmm2, xmm4);      /* xmm4 = i3 */ \
48     movdqa_m2r(*I(5), xmm7);     /* xmm7 = i5 */ \
49     \
50     pmulhw_r2r(xmm6, xmm4);      /* xmm4 = c3 * i3 - i3 */ \
51     movdqa_m2r(*C(5), xmm1);     /* xmm1 = c5 */ \
52     \
53     pmulhw_r2r(xmm7, xmm6);      /* xmm6 = c3 * i5 - i5 */ \
54     movdqa_r2r(xmm1, xmm5);      /* xmm5 = c5 */ \
55     \
56     pmulhw_r2r(xmm2, xmm1);      /* xmm1 = c5 * i3 - i3 */ \
57     movdqa_m2r(*I(1), xmm3);     /* xmm3 = i1 */ \
58     \
59     pmulhw_r2r(xmm7, xmm5);      /* xmm5 = c5 * i5 - i5 */ \
60     movdqa_m2r(*C(1), xmm0);     /* xmm0 = c1 */ \
61     \
62     /* all registers are in use */ \
63     \
64     paddw_r2r(xmm2, xmm4);       /* xmm4 = c3 * i3 */ \
65     paddw_r2r(xmm7, xmm6);       /* xmm6 = c3 * i5 */ \
66     \
67     paddw_r2r(xmm1, xmm2);       /* xmm2 = c5 * i3 */ \
68     movdqa_m2r(*I(7), xmm1);     /* xmm1 = i7 */ \
69     \
70     paddw_r2r(xmm5, xmm7);       /* xmm7 = c5 * i5 */ \
71     movdqa_r2r(xmm0, xmm5);      /* xmm5 = c1 */ \
72     \
73     pmulhw_r2r(xmm3, xmm0);      /* xmm0 = c1 * i1 - i1 */ \
74     paddsw_r2r(xmm7, xmm4);      /* xmm4 = c3 * i3 + c5 * i5 = C */ \
75     \
76     pmulhw_r2r(xmm1, xmm5);      /* xmm5 = c1 * i7 - i7 */ \
77     movdqa_m2r(*C(7), xmm7);     /* xmm7 = c7 */ \
78     \
79     psubsw_r2r(xmm2, xmm6);      /* xmm6 = c3 * i5 - c5 * i3 = D */ \
80     paddw_r2r(xmm3, xmm0);       /* xmm0 = c1 * i1 */ \
81     \
82     pmulhw_r2r(xmm7, xmm3);      /* xmm3 = c7 * i1 */ \
83     movdqa_m2r(*I(2), xmm2);     /* xmm2 = i2 */ \
84     \
85     pmulhw_r2r(xmm1, xmm7);      /* xmm7 = c7 * i7 */ \
86     paddw_r2r(xmm1, xmm5);       /* xmm5 = c1 * i7 */ \
87     \
88     movdqa_r2r(xmm2, xmm1);      /* xmm1 = i2 */ \
89     pmulhw_m2r(*C(2), xmm2);     /* xmm2 = i2 * c2 -i2 */ \
90     \
91     psubsw_r2r(xmm5, xmm3);      /* xmm3 = c7 * i1 - c1 * i7 = B */ \
92     movdqa_m2r(*I(6), xmm5);     /* xmm5 = i6 */ \
93     \
94     paddsw_r2r(xmm7, xmm0);      /* xmm0 = c1 * i1 + c7 * i7 = A */ \
95     movdqa_r2r(xmm5, xmm7);      /* xmm7 = i6 */ \
96     \
97     psubsw_r2r(xmm4, xmm0);      /* xmm0 = A - C */ \
98     pmulhw_m2r(*C(2), xmm5);     /* xmm5 = c2 * i6 - i6 */ \
99     \
100     paddw_r2r(xmm1, xmm2);       /* xmm2 = i2 * c2 */ \
101     pmulhw_m2r(*C(6), xmm1);     /* xmm1 = c6 * i2 */ \
102     \
103     paddsw_r2r(xmm4, xmm4);      /* xmm4 = C + C */ \
104     paddsw_r2r(xmm0, xmm4);      /* xmm4 = A + C = C. */ \
105     \
106     psubsw_r2r(xmm6, xmm3);      /* xmm3 = B - D */ \
107     paddw_r2r(xmm7, xmm5);       /* xmm5 = c2 * i6 */ \
108     \
109     paddsw_r2r(xmm6, xmm6);      /* xmm6 = D + D */ \
110     pmulhw_m2r(*C(6), xmm7);     /* xmm7 = c6 * i6 */ \
111     \
112     paddsw_r2r(xmm3, xmm6);      /* xmm6 = B + D = D. */ \
113     movdqa_r2m(xmm4, *I(1));     /* Save C. at I(1) */ \
114     \
115     psubsw_r2r(xmm5, xmm1);      /* xmm1 = c6 * i2 - c2 * i6 = H */ \
116     movdqa_m2r(*C(4), xmm4);     /* xmm4 = c4 */ \
117     \
118     movdqa_r2r(xmm3, xmm5);      /* xmm5 = B - D */ \
119     pmulhw_r2r(xmm4, xmm3);      /* xmm3 = ( c4 -1 ) * ( B - D ) */ \
120     \
121     paddsw_r2r(xmm2, xmm7);      /* xmm7 = c2 * i2 + c6 * i6 = G */ \
122     movdqa_r2m(xmm6, *I(2));     /* Save D. at I(2) */ \
123     \
124     movdqa_r2r(xmm0, xmm2);      /* xmm2 = A - C */ \
125     movdqa_m2r(*I(0), xmm6);     /* xmm6 = i0 */ \
126     \
127     pmulhw_r2r(xmm4, xmm0);      /* xmm0 = ( c4 - 1 ) * ( A - C ) = A. */ \
128     paddw_r2r(xmm3, xmm5);       /* xmm5 = c4 * ( B - D ) = B. */ \
129     \
130     movdqa_m2r(*I(4), xmm3);     /* xmm3 = i4 */ \
131     psubsw_r2r(xmm1, xmm5);      /* xmm5 = B. - H = B.. */ \
132     \
133     paddw_r2r(xmm0, xmm2);       /* xmm2 = c4 * ( A - C) = A. */ \
134     psubsw_r2r(xmm3, xmm6);      /* xmm6 = i0 - i4 */ \
135     \
136     movdqa_r2r(xmm6, xmm0);      /* xmm0 = i0 - i4 */ \
137     pmulhw_r2r(xmm4, xmm6);      /* xmm6 = (c4 - 1) * (i0 - i4) = F */ \
138     \
139     paddsw_r2r(xmm3, xmm3);      /* xmm3 = i4 + i4 */ \
140     paddsw_r2r(xmm1, xmm1);      /* xmm1 = H + H */ \
141     \
142     paddsw_r2r(xmm0, xmm3);      /* xmm3 = i0 + i4 */ \
143     paddsw_r2r(xmm5, xmm1);      /* xmm1 = B. + H = H. */ \
144     \
145     pmulhw_r2r(xmm3, xmm4);      /* xmm4 = ( c4 - 1 ) * ( i0 + i4 )  */ \
146     paddw_r2r(xmm0, xmm6);       /* xmm6 = c4 * ( i0 - i4 ) */ \
147     \
148     psubsw_r2r(xmm2, xmm6);      /* xmm6 = F - A. = F. */ \
149     paddsw_r2r(xmm2, xmm2);      /* xmm2 = A. + A. */ \
150     \
151     movdqa_m2r(*I(1), xmm0);     /* Load        C. from I(1) */ \
152     paddsw_r2r(xmm6, xmm2);      /* xmm2 = F + A. = A.. */ \
153     \
154     paddw_r2r(xmm3, xmm4);       /* xmm4 = c4 * ( i0 + i4 ) = 3 */ \
155     psubsw_r2r(xmm1, xmm2);      /* xmm2 = A.. - H. = R2 */ \
156     \
157     paddsw_m2r(*Eight, xmm2);    /* Adjust R2 and R1 before shifting */ \
158     paddsw_r2r(xmm1, xmm1);      /* xmm1 = H. + H. */ \
159     \
160     paddsw_r2r(xmm2, xmm1);      /* xmm1 = A.. + H. = R1 */ \
161     psraw_i2r(4, xmm2);          /* xmm2 = op2 */ \
162     \
163     psubsw_r2r(xmm7, xmm4);      /* xmm4 = E - G = E. */ \
164     psraw_i2r(4, xmm1);          /* xmm1 = op1 */ \
165     \
166     movdqa_m2r(*I(2), xmm3);     /* Load D. from I(2) */ \
167     paddsw_r2r(xmm7, xmm7);      /* xmm7 = G + G */ \
168     \
169     movdqa_r2m(xmm2, *O(2));     /* Write out op2 */ \
170     paddsw_r2r(xmm4, xmm7);      /* xmm7 = E + G = G. */ \
171     \
172     movdqa_r2m(xmm1, *O(1));     /* Write out op1 */ \
173     psubsw_r2r(xmm3, xmm4);      /* xmm4 = E. - D. = R4 */ \
174     \
175     paddsw_m2r(*Eight, xmm4);    /* Adjust R4 and R3 before shifting */ \
176     paddsw_r2r(xmm3, xmm3);      /* xmm3 = D. + D. */ \
177     \
178     paddsw_r2r(xmm4, xmm3);      /* xmm3 = E. + D. = R3 */ \
179     psraw_i2r(4, xmm4);          /* xmm4 = op4 */ \
180     \
181     psubsw_r2r(xmm5, xmm6);      /* xmm6 = F. - B..= R6 */ \
182     psraw_i2r(4, xmm3);          /* xmm3 = op3 */ \
183     \
184     paddsw_m2r(*Eight, xmm6);    /* Adjust R6 and R5 before shifting */ \
185     paddsw_r2r(xmm5, xmm5);      /* xmm5 = B.. + B.. */ \
186     \
187     paddsw_r2r(xmm6, xmm5);      /* xmm5 = F. + B.. = R5 */ \
188     psraw_i2r(4, xmm6);          /* xmm6 = op6 */ \
189     \
190     movdqa_r2m(xmm4, *O(4));     /* Write out op4 */ \
191     psraw_i2r(4, xmm5);          /* xmm5 = op5 */ \
192     \
193     movdqa_r2m(xmm3, *O(3));     /* Write out op3 */ \
194     psubsw_r2r(xmm0, xmm7);      /* xmm7 = G. - C. = R7 */ \
195     \
196     paddsw_m2r(*Eight, xmm7);    /* Adjust R7 and R0 before shifting */ \
197     paddsw_r2r(xmm0, xmm0);      /* xmm0 = C. + C. */ \
198     \
199     paddsw_r2r(xmm7, xmm0);      /* xmm0 = G. + C. */ \
200     psraw_i2r(4, xmm7);          /* xmm7 = op7 */ \
201     \
202     movdqa_r2m(xmm6, *O(6));     /* Write out op6 */ \
203     psraw_i2r(4, xmm0);          /* xmm0 = op0 */ \
204     \
205     movdqa_r2m(xmm5, *O(5));     /* Write out op5 */ \
206     movdqa_r2m(xmm7, *O(7));     /* Write out op7 */ \
207     \
208     movdqa_r2m(xmm0, *O(0));     /* Write out op0 */ \
209     \
210 } /* End of SSE2_Column_IDCT macro */
211
212
213 #define SSE2_Row_IDCT() {        \
214     \
215     movdqa_m2r(*I(3), xmm2);     /* xmm2 = i3 */ \
216     movdqa_m2r(*C(3), xmm6);     /* xmm6 = c3 */ \
217     \
218     movdqa_r2r(xmm2, xmm4);      /* xmm4 = i3 */ \
219     movdqa_m2r(*I(5), xmm7);     /* xmm7 = i5 */ \
220     \
221     pmulhw_r2r(xmm6, xmm4);      /* xmm4 = c3 * i3 - i3 */ \
222     movdqa_m2r(*C(5), xmm1);     /* xmm1 = c5 */ \
223     \
224     pmulhw_r2r(xmm7, xmm6);      /* xmm6 = c3 * i5 - i5 */ \
225     movdqa_r2r(xmm1, xmm5);      /* xmm5 = c5 */ \
226     \
227     pmulhw_r2r(xmm2, xmm1);      /* xmm1 = c5 * i3 - i3 */ \
228     movdqa_m2r(*I(1), xmm3);     /* xmm3 = i1 */ \
229     \
230     pmulhw_r2r(xmm7, xmm5);      /* xmm5 = c5 * i5 - i5 */ \
231     movdqa_m2r(*C(1), xmm0);     /* xmm0 = c1 */ \
232     \
233     /* all registers are in use */ \
234     \
235     paddw_r2r(xmm2, xmm4);      /* xmm4 = c3 * i3 */ \
236     paddw_r2r(xmm7, xmm6);      /* xmm6 = c3 * i5 */ \
237     \
238     paddw_r2r(xmm1, xmm2);      /* xmm2 = c5 * i3 */ \
239     movdqa_m2r(*I(7), xmm1);    /* xmm1 = i7 */ \
240     \
241     paddw_r2r(xmm5, xmm7);      /* xmm7 = c5 * i5 */ \
242     movdqa_r2r(xmm0, xmm5);     /* xmm5 = c1 */ \
243     \
244     pmulhw_r2r(xmm3, xmm0);     /* xmm0 = c1 * i1 - i1 */ \
245     paddsw_r2r(xmm7, xmm4);     /* xmm4 = c3 * i3 + c5 * i5 = C */ \
246     \
247     pmulhw_r2r(xmm1, xmm5);     /* xmm5 = c1 * i7 - i7 */ \
248     movdqa_m2r(*C(7), xmm7);    /* xmm7 = c7 */ \
249     \
250     psubsw_r2r(xmm2, xmm6);     /* xmm6 = c3 * i5 - c5 * i3 = D */ \
251     paddw_r2r(xmm3, xmm0);      /* xmm0 = c1 * i1 */ \
252     \
253     pmulhw_r2r(xmm7, xmm3);     /* xmm3 = c7 * i1 */ \
254     movdqa_m2r(*I(2), xmm2);    /* xmm2 = i2 */ \
255     \
256     pmulhw_r2r(xmm1, xmm7);     /* xmm7 = c7 * i7 */ \
257     paddw_r2r(xmm1, xmm5);      /* xmm5 = c1 * i7 */ \
258     \
259     movdqa_r2r(xmm2, xmm1);     /* xmm1 = i2 */ \
260     pmulhw_m2r(*C(2), xmm2);    /* xmm2 = i2 * c2 -i2 */ \
261     \
262     psubsw_r2r(xmm5, xmm3);     /* xmm3 = c7 * i1 - c1 * i7 = B */ \
263     movdqa_m2r(*I(6), xmm5);    /* xmm5 = i6 */ \
264     \
265     paddsw_r2r(xmm7, xmm0);     /* xmm0 = c1 * i1 + c7 * i7        = A */ \
266     movdqa_r2r(xmm5, xmm7);     /* xmm7 = i6 */ \
267     \
268     psubsw_r2r(xmm4, xmm0);     /* xmm0 = A - C */ \
269     pmulhw_m2r(*C(2), xmm5);    /* xmm5 = c2 * i6 - i6 */ \
270     \
271     paddw_r2r(xmm1, xmm2);      /* xmm2 = i2 * c2 */ \
272     pmulhw_m2r(*C(6), xmm1);    /* xmm1 = c6 * i2 */ \
273     \
274     paddsw_r2r(xmm4, xmm4);     /* xmm4 = C + C */ \
275     paddsw_r2r(xmm0, xmm4);     /* xmm4 = A + C = C. */ \
276     \
277     psubsw_r2r(xmm6, xmm3);     /* xmm3 = B - D */ \
278     paddw_r2r(xmm7, xmm5);      /* xmm5 = c2 * i6 */ \
279     \
280     paddsw_r2r(xmm6, xmm6);     /* xmm6 = D + D */ \
281     pmulhw_m2r(*C(6), xmm7);    /* xmm7 = c6 * i6 */ \
282     \
283     paddsw_r2r(xmm3, xmm6);     /* xmm6 = B + D = D. */ \
284     movdqa_r2m(xmm4, *I(1));    /* Save C. at I(1)        */ \
285     \
286     psubsw_r2r(xmm5, xmm1);     /* xmm1 = c6 * i2 - c2 * i6 = H */ \
287     movdqa_m2r(*C(4), xmm4);    /* xmm4 = c4 */ \
288     \
289     movdqa_r2r(xmm3, xmm5);     /* xmm5 = B - D */ \
290     pmulhw_r2r(xmm4, xmm3);     /* xmm3 = ( c4 -1 ) * ( B - D ) */ \
291     \
292     paddsw_r2r(xmm2, xmm7);     /* xmm7 = c2 * i2 + c6 * i6 = G */ \
293     movdqa_r2m(xmm6, *I(2));    /* Save D. at I(2) */ \
294     \
295     movdqa_r2r(xmm0, xmm2);     /* xmm2 = A - C */ \
296     movdqa_m2r(*I(0), xmm6);    /* xmm6 = i0 */ \
297     \
298     pmulhw_r2r(xmm4, xmm0);     /* xmm0 = ( c4 - 1 ) * ( A - C ) = A. */ \
299     paddw_r2r(xmm3, xmm5);      /* xmm5 = c4 * ( B - D ) = B. */ \
300     \
301     movdqa_m2r(*I(4), xmm3);    /* xmm3 = i4 */ \
302     psubsw_r2r(xmm1, xmm5);     /* xmm5 = B. - H = B.. */ \
303     \
304     paddw_r2r(xmm0, xmm2);      /* xmm2 = c4 * ( A - C) = A. */ \
305     psubsw_r2r(xmm3, xmm6);     /* xmm6 = i0 - i4 */ \
306     \
307     movdqa_r2r(xmm6, xmm0);     /* xmm0 = i0 - i4 */ \
308     pmulhw_r2r(xmm4, xmm6);     /* xmm6 = ( c4 - 1 ) * ( i0 - i4 ) = F */ \
309     \
310     paddsw_r2r(xmm3, xmm3);     /* xmm3 = i4 + i4 */ \
311     paddsw_r2r(xmm1, xmm1);     /* xmm1 = H + H */ \
312     \
313     paddsw_r2r(xmm0, xmm3);     /* xmm3 = i0 + i4 */ \
314     paddsw_r2r(xmm5, xmm1);     /* xmm1 = B. + H = H. */ \
315     \
316     pmulhw_r2r(xmm3, xmm4);     /* xmm4 = ( c4 - 1 ) * ( i0 + i4 )  */ \
317     paddw_r2r(xmm0, xmm6);      /* xmm6 = c4 * ( i0 - i4 ) */ \
318     \
319     psubsw_r2r(xmm2, xmm6);     /* xmm6 = F - A. = F. */ \
320     paddsw_r2r(xmm2, xmm2);     /* xmm2 = A. + A. */ \
321     \
322     movdqa_m2r(*I(1), xmm0);    /* Load C. from I(1) */ \
323     paddsw_r2r(xmm6, xmm2);     /* xmm2 = F + A. = A.. */ \
324     \
325     paddw_r2r(xmm3, xmm4);      /* xmm4 = c4 * ( i0 + i4 ) = 3 */ \
326     psubsw_r2r(xmm1, xmm2);     /* xmm2 = A.. - H. = R2 */ \
327     \
328     paddsw_r2r(xmm1, xmm1);     /* xmm1 = H. + H. */ \
329     paddsw_r2r(xmm2, xmm1);     /* xmm1 = A.. + H. = R1 */ \
330     \
331     psubsw_r2r(xmm7, xmm4);     /* xmm4 = E - G = E. */ \
332     \
333     movdqa_m2r(*I(2), xmm3);    /* Load D. from I(2) */ \
334     paddsw_r2r(xmm7, xmm7);     /* xmm7 = G + G */ \
335     \
336     movdqa_r2m(xmm2, *I(2));    /* Write out op2 */ \
337     paddsw_r2r(xmm4, xmm7);     /* xmm7 = E + G = G. */ \
338     \
339     movdqa_r2m(xmm1, *I(1));    /* Write out op1 */ \
340     psubsw_r2r(xmm3, xmm4);     /* xmm4 = E. - D. = R4 */ \
341     \
342     paddsw_r2r(xmm3, xmm3);     /* xmm3 = D. + D. */ \
343     \
344     paddsw_r2r(xmm4, xmm3);     /* xmm3 = E. + D. = R3 */ \
345     \
346     psubsw_r2r(xmm5, xmm6);     /* xmm6 = F. - B..= R6 */ \
347     \
348     paddsw_r2r(xmm5, xmm5);     /* xmm5 = B.. + B.. */ \
349     \
350     paddsw_r2r(xmm6, xmm5);     /* xmm5 = F. + B.. = R5 */ \
351     \
352     movdqa_r2m(xmm4, *I(4));    /* Write out op4 */ \
353     \
354     movdqa_r2m(xmm3, *I(3));    /* Write out op3 */ \
355     psubsw_r2r(xmm0, xmm7);     /* xmm7 = G. - C. = R7 */ \
356     \
357     paddsw_r2r(xmm0, xmm0);     /* xmm0 = C. + C. */ \
358     \
359     paddsw_r2r(xmm7, xmm0);     /* xmm0 = G. + C. */ \
360     \
361     movdqa_r2m(xmm6, *I(6));    /* Write out op6 */ \
362     \
363     movdqa_r2m(xmm5, *I(5));    /* Write out op5 */ \
364     movdqa_r2m(xmm7, *I(7));    /* Write out op7 */ \
365     \
366     movdqa_r2m(xmm0, *I(0));    /* Write out op0 */ \
367     \
368 } /* End of SSE2_Row_IDCT macro */
369
370
371 #define SSE2_Transpose() {    \
372     \
373     movdqa_m2r(*I(4), xmm4);    /* xmm4=e7e6e5e4e3e2e1e0 */ \
374     movdqa_m2r(*I(5), xmm0);    /* xmm4=f7f6f5f4f3f2f1f0 */ \
375     \
376     movdqa_r2r(xmm4, xmm5);     /* make a copy */ \
377     punpcklwd_r2r(xmm0, xmm4);  /* xmm4=f3e3f2e2f1e1f0e0 */ \
378     \
379     punpckhwd_r2r(xmm0, xmm5);  /* xmm5=f7e7f6e6f5e5f4e4 */ \
380     movdqa_m2r(*I(6), xmm6);    /* xmm6=g7g6g5g4g3g2g1g0 */ \
381     \
382     movdqa_m2r(*I(7), xmm0);    /* xmm0=h7h6h5h4h3h2h1h0 */ \
383     movdqa_r2r(xmm6, xmm7);     /* make a copy */ \
384     \
385     punpcklwd_r2r(xmm0, xmm6);  /* xmm6=h3g3h3g2h1g1h0g0 */ \
386     punpckhwd_r2r(xmm0, xmm7);  /* xmm7=h7g7h6g6h5g5h4g4 */ \
387     \
388     movdqa_r2r(xmm4, xmm3);     /* make a copy */ \
389     punpckldq_r2r(xmm6, xmm4);  /* xmm4=h1g1f1e1h0g0f0e0 */ \
390     \
391     punpckhdq_r2r(xmm6, xmm3);  /* xmm3=h3g3g3e3h2g2f2e2 */ \
392     movdqa_r2m(xmm3, *I(6));    /* save h3g3g3e3h2g2f2e2 */ \
393     /* Free xmm6 */ \
394     movdqa_r2r(xmm5, xmm6);     /* make a copy */ \
395     punpckldq_r2r(xmm7, xmm5);  /* xmm5=h5g5f5e5h4g4f4e4 */ \
396     \
397     punpckhdq_r2r(xmm7, xmm6);  /* xmm6=h7g7f7e7h6g6f6e6 */ \
398     movdqa_m2r(*I(0), xmm0);    /* xmm0=a7a6a5a4a3a2a1a0 */ \
399     /* Free xmm7 */ \
400     movdqa_m2r(*I(1), xmm1);    /* xmm1=b7b6b5b4b3b2b1b0 */ \
401     movdqa_r2r(xmm0, xmm7);     /* make a copy */ \
402     \
403     punpcklwd_r2r(xmm1, xmm0);  /* xmm0=b3a3b2a2b1a1b0a0 */ \
404     punpckhwd_r2r(xmm1, xmm7);  /* xmm7=b7a7b6a6b5a5b4a4 */ \
405     /* Free xmm1 */ \
406     movdqa_m2r(*I(2), xmm2);    /* xmm2=c7c6c5c4c3c2c1c0 */ \
407     movdqa_m2r(*I(3), xmm3);    /* xmm3=d7d6d5d4d3d2d1d0 */ \
408     \
409     movdqa_r2r(xmm2, xmm1);     /* make a copy */ \
410     punpcklwd_r2r(xmm3, xmm2);  /* xmm2=d3c3d2c2d1c1d0c0 */ \
411     \
412     punpckhwd_r2r(xmm3, xmm1);  /* xmm1=d7c7d6c6d5c5d4c4 */ \
413     movdqa_r2r(xmm0, xmm3);     /* make a copy        */ \
414     \
415     punpckldq_r2r(xmm2, xmm0);  /* xmm0=d1c1b1a1d0c0b0a0 */ \
416     punpckhdq_r2r(xmm2, xmm3);  /* xmm3=d3c3b3a3d2c2b2a2 */ \
417     /* Free xmm2 */ \
418     movdqa_r2r(xmm7, xmm2);     /* make a copy */ \
419     punpckldq_r2r(xmm1, xmm2);  /* xmm2=d5c5b5a5d4c4b4a4 */ \
420     \
421     punpckhdq_r2r(xmm1, xmm7);  /* xmm7=d7c7b7a7d6c6b6a6 */ \
422     movdqa_r2r(xmm0, xmm1);     /* make a copy */ \
423     \
424     punpcklqdq_r2r(xmm4, xmm0); /* xmm0=h0g0f0e0d0c0b0a0 */ \
425     punpckhqdq_r2r(xmm4, xmm1); /* xmm1=h1g1g1e1d1c1b1a1 */ \
426     \
427     movdqa_r2m(xmm0, *I(0));    /* save I(0) */ \
428     movdqa_r2m(xmm1, *I(1));    /* save I(1) */ \
429     \
430     movdqa_m2r(*I(6), xmm0);    /* load h3g3g3e3h2g2f2e2 */ \
431     movdqa_r2r(xmm3, xmm1);     /* make a copy */ \
432     \
433     punpcklqdq_r2r(xmm0, xmm1); /* xmm1=h2g2f2e2d2c2b2a2 */ \
434     punpckhqdq_r2r(xmm0, xmm3); /* xmm3=h3g3f3e3d3c3b3a3 */ \
435     \
436     movdqa_r2r(xmm2, xmm4);     /* make a copy */ \
437     punpcklqdq_r2r(xmm5, xmm4); /* xmm4=h4g4f4e4d4c4b4a4 */ \
438     \
439     punpckhqdq_r2r(xmm5, xmm2); /* xmm2=h5g5f5e5d5c5b5a5 */ \
440     movdqa_r2m(xmm1, *I(2));    /* save I(2) */ \
441     \
442     movdqa_r2m(xmm3, *I(3));    /* save I(3) */ \
443     movdqa_r2m(xmm4, *I(4));    /* save I(4) */ \
444     \
445     movdqa_r2m(xmm2, *I(5));    /* save I(5) */ \
446     movdqa_r2r(xmm7, xmm5);     /* make a copy */ \
447     \
448     punpcklqdq_r2r(xmm6, xmm5); /* xmm5=h6g6f6e6d6c6b6a6 */ \
449     punpckhqdq_r2r(xmm6, xmm7); /* xmm7=h7g7f7e7d7c7b7a7 */ \
450     \
451     movdqa_r2m(xmm5, *I(6));    /* save I(6) */ \
452     movdqa_r2m(xmm7, *I(7));    /* save I(7) */ \
453     \
454 } /* End of Transpose Macro */
455
456 void ff_vp3_idct_sse2(int16_t *input_data)
457 {
458     unsigned char *input_bytes = (unsigned char *)input_data;
459     unsigned char *output_data_bytes = (unsigned char *)input_data;
460     const unsigned char *idct_data_bytes = (const unsigned char *)ff_vp3_idct_data;
461     const unsigned char *Eight = (const unsigned char *)&ff_pw_8;
462
463 #define eax input_bytes
464 #define edx idct_data_bytes
465
466 #define I(i) (eax + 16 * i)
467 #define O(i) (ebx + 16 * i)
468 #define C(i) (edx + 16 * (i-1))
469
470 #define ebx output_data_bytes
471
472     SSE2_Row_IDCT();
473
474     SSE2_Transpose();
475
476     SSE2_Column_IDCT();
477 }
478
479 void ff_vp3_idct_put_sse2(uint8_t *dest, int line_size, DCTELEM *block)
480 {
481     ff_vp3_idct_sse2(block);
482     put_signed_pixels_clamped_mmx(block, dest, line_size);
483 }
484
485 void ff_vp3_idct_add_sse2(uint8_t *dest, int line_size, DCTELEM *block)
486 {
487     ff_vp3_idct_sse2(block);
488     add_pixels_clamped_mmx(block, dest, line_size);
489 }