]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/vp3dsp.asm
vp3: don't use calls to inline asm in yasm code.
[ffmpeg] / libavcodec / x86 / vp3dsp.asm
1 ;******************************************************************************
2 ;* MMX/SSE2-optimized functions for the VP3 decoder
3 ;* Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org>
4 ;*
5 ;* This file is part of Libav.
6 ;*
7 ;* Libav is free software; you can redistribute it and/or
8 ;* modify it under the terms of the GNU Lesser General Public
9 ;* License as published by the Free Software Foundation; either
10 ;* version 2.1 of the License, or (at your option) any later version.
11 ;*
12 ;* Libav is distributed in the hope that it will be useful,
13 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 ;* Lesser General Public License for more details.
16 ;*
17 ;* You should have received a copy of the GNU Lesser General Public
18 ;* License along with Libav; if not, write to the Free Software
19 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ;******************************************************************************
21
22 %include "x86inc.asm"
23 %include "x86util.asm"
24
25 ; MMX-optimized functions cribbed from the original VP3 source code.
26
27 SECTION_RODATA
28
29 vp3_idct_data: times 8 dw 64277
30                times 8 dw 60547
31                times 8 dw 54491
32                times 8 dw 46341
33                times 8 dw 36410
34                times 8 dw 25080
35                times 8 dw 12785
36
37 cextern pb_1
38 cextern pb_3
39 cextern pb_7
40 cextern pb_1F
41 cextern pb_80
42 cextern pb_81
43
44 cextern pw_8
45
46 SECTION .text
47
48 ; this is off by one or two for some cases when filter_limit is greater than 63
49 ; in:  p0 in mm6, p1 in mm4, p2 in mm2, p3 in mm1
50 ; out: p1 in mm4, p2 in mm3
51 %macro VP3_LOOP_FILTER 0
52     movq          m7, m6
53     pand          m6, [pb_7]    ; p0&7
54     psrlw         m7, 3
55     pand          m7, [pb_1F]   ; p0>>3
56     movq          m3, m2        ; p2
57     pxor          m2, m4
58     pand          m2, [pb_1]    ; (p2^p1)&1
59     movq          m5, m2
60     paddb         m2, m2
61     paddb         m2, m5        ; 3*(p2^p1)&1
62     paddb         m2, m6        ; extra bits lost in shifts
63     pcmpeqb       m0, m0
64     pxor          m1, m0        ; 255 - p3
65     pavgb         m1, m2        ; (256 - p3 + extrabits) >> 1
66     pxor          m0, m4        ; 255 - p1
67     pavgb         m0, m3        ; (256 + p2-p1) >> 1
68     paddb         m1, [pb_3]
69     pavgb         m1, m0        ; 128+2+(   p2-p1  - p3) >> 2
70     pavgb         m1, m0        ; 128+1+(3*(p2-p1) - p3) >> 3
71     paddusb       m7, m1        ; d+128+1
72     movq          m6, [pb_81]
73     psubusb       m6, m7
74     psubusb       m7, [pb_81]
75
76     movq          m5, [r2+516]  ; flim
77     pminub        m6, m5
78     pminub        m7, m5
79     movq          m0, m6
80     movq          m1, m7
81     paddb         m6, m6
82     paddb         m7, m7
83     pminub        m6, m5
84     pminub        m7, m5
85     psubb         m6, m0
86     psubb         m7, m1
87     paddusb       m4, m7
88     psubusb       m4, m6
89     psubusb       m3, m7
90     paddusb       m3, m6
91 %endmacro
92
93 %macro STORE_4_WORDS 1
94     movd         r2d, %1
95     mov  [r0     -1], r2w
96     psrlq         %1, 32
97     shr           r2, 16
98     mov  [r0+r1  -1], r2w
99     movd         r2d, %1
100     mov  [r0+r1*2-1], r2w
101     shr           r2, 16
102     mov  [r0+r3  -1], r2w
103 %endmacro
104
105 INIT_MMX
106 cglobal vp3_v_loop_filter_mmx2, 3, 4
107 %if ARCH_X86_64
108     movsxd        r1, r1d
109 %endif
110     mov           r3, r1
111     neg           r1
112     movq          m6, [r0+r1*2]
113     movq          m4, [r0+r1  ]
114     movq          m2, [r0     ]
115     movq          m1, [r0+r3  ]
116
117     VP3_LOOP_FILTER
118
119     movq     [r0+r1], m4
120     movq     [r0   ], m3
121     RET
122
123 cglobal vp3_h_loop_filter_mmx2, 3, 4
124 %if ARCH_X86_64
125     movsxd        r1, r1d
126 %endif
127     lea           r3, [r1*3]
128
129     movd          m6, [r0     -2]
130     movd          m4, [r0+r1  -2]
131     movd          m2, [r0+r1*2-2]
132     movd          m1, [r0+r3  -2]
133     lea           r0, [r0+r1*4  ]
134     punpcklbw     m6, [r0     -2]
135     punpcklbw     m4, [r0+r1  -2]
136     punpcklbw     m2, [r0+r1*2-2]
137     punpcklbw     m1, [r0+r3  -2]
138     sub           r0, r3
139     sub           r0, r1
140
141     TRANSPOSE4x4B  6, 4, 2, 1, 0
142     VP3_LOOP_FILTER
143     SBUTTERFLY    bw, 4, 3, 5
144
145     STORE_4_WORDS m4
146     lea           r0, [r0+r1*4  ]
147     STORE_4_WORDS m3
148     RET
149
150 ; from original comments: The Macro does IDct on 4 1-D Dcts
151 %macro BeginIDCT 0
152     movq          m2, I(3)
153     movq          m6, C(3)
154     movq          m4, m2
155     movq          m7, J(5)
156     pmulhw        m4, m6        ; r4 = c3*i3 - i3
157     movq          m1, C(5)
158     pmulhw        m6, m7        ; r6 = c3*i5 - i5
159     movq          m5, m1
160     pmulhw        m1, m2        ; r1 = c5*i3 - i3
161     movq          m3, I(1)
162     pmulhw        m5, m7        ; r5 = c5*i5 - i5
163     movq          m0, C(1)
164     paddw         m4, m2        ; r4 = c3*i3
165     paddw         m6, m7        ; r6 = c3*i5
166     paddw         m2, m1        ; r2 = c5*i3
167     movq          m1, J(7)
168     paddw         m7, m5        ; r7 = c5*i5
169     movq          m5, m0        ; r5 = c1
170     pmulhw        m0, m3        ; r0 = c1*i1 - i1
171     paddsw        m4, m7        ; r4 = C = c3*i3 + c5*i5
172     pmulhw        m5, m1        ; r5 = c1*i7 - i7
173     movq          m7, C(7)
174     psubsw        m6, m2        ; r6 = D = c3*i5 - c5*i3
175     paddw         m0, m3        ; r0 = c1*i1
176     pmulhw        m3, m7        ; r3 = c7*i1
177     movq          m2, I(2)
178     pmulhw        m7, m1        ; r7 = c7*i7
179     paddw         m5, m1        ; r5 = c1*i7
180     movq          m1, m2        ; r1 = i2
181     pmulhw        m2, C(2)      ; r2 = c2*i2 - i2
182     psubsw        m3, m5        ; r3 = B = c7*i1 - c1*i7
183     movq          m5, J(6)
184     paddsw        m0, m7        ; r0 = A = c1*i1 + c7*i7
185     movq          m7, m5        ; r7 = i6
186     psubsw        m0, m4        ; r0 = A - C
187     pmulhw        m5, C(2)      ; r5 = c2*i6 - i6
188     paddw         m2, m1        ; r2 = c2*i2
189     pmulhw        m1, C(6)      ; r1 = c6*i2
190     paddsw        m4, m4        ; r4 = C + C
191     paddsw        m4, m0        ; r4 = C. = A + C
192     psubsw        m3, m6        ; r3 = B - D
193     paddw         m5, m7        ; r5 = c2*i6
194     paddsw        m6, m6        ; r6 = D + D
195     pmulhw        m7, C(6)      ; r7 = c6*i6
196     paddsw        m6, m3        ; r6 = D. = B + D
197     movq        I(1), m4        ; save C. at I(1)
198     psubsw        m1, m5        ; r1 = H = c6*i2 - c2*i6
199     movq          m4, C(4)
200     movq          m5, m3        ; r5 = B - D
201     pmulhw        m3, m4        ; r3 = (c4 - 1) * (B - D)
202     paddsw        m7, m2        ; r3 = (c4 - 1) * (B - D)
203     movq        I(2), m6        ; save D. at I(2)
204     movq          m2, m0        ; r2 = A - C
205     movq          m6, I(0)
206     pmulhw        m0, m4        ; r0 = (c4 - 1) * (A - C)
207     paddw         m5, m3        ; r5 = B. = c4 * (B - D)
208     movq          m3, J(4)
209     psubsw        m5, m1        ; r5 = B.. = B. - H
210     paddw         m2, m0        ; r0 = A. = c4 * (A - C)
211     psubsw        m6, m3        ; r6 = i0 - i4
212     movq          m0, m6
213     pmulhw        m6, m4        ; r6 = (c4 - 1) * (i0 - i4)
214     paddsw        m3, m3        ; r3 = i4 + i4
215     paddsw        m1, m1        ; r1 = H + H
216     paddsw        m3, m0        ; r3 = i0 + i4
217     paddsw        m1, m5        ; r1 = H. = B + H
218     pmulhw        m4, m3        ; r4 = (c4 - 1) * (i0 + i4)
219     paddsw        m6, m0        ; r6 = F = c4 * (i0 - i4)
220     psubsw        m6, m2        ; r6 = F. = F - A.
221     paddsw        m2, m2        ; r2 = A. + A.
222     movq          m0, I(1)      ; r0 = C.
223     paddsw        m2, m6        ; r2 = A.. = F + A.
224     paddw         m4, m3        ; r4 = E = c4 * (i0 + i4)
225     psubsw        m2, m1        ; r2 = R2 = A.. - H.
226 %endmacro
227
228 ; RowIDCT gets ready to transpose
229 %macro RowIDCT 0
230     BeginIDCT
231     movq          m3, I(2)      ; r3 = D.
232     psubsw        m4, m7        ; r4 = E. = E - G
233     paddsw        m1, m1        ; r1 = H. + H.
234     paddsw        m7, m7        ; r7 = G + G
235     paddsw        m1, m2        ; r1 = R1 = A.. + H.
236     paddsw        m7, m4        ; r1 = R1 = A.. + H.
237     psubsw        m4, m3        ; r4 = R4 = E. - D.
238     paddsw        m3, m3
239     psubsw        m6, m5        ; r6 = R6 = F. - B..
240     paddsw        m5, m5
241     paddsw        m3, m4        ; r3 = R3 = E. + D.
242     paddsw        m5, m6        ; r5 = R5 = F. + B..
243     psubsw        m7, m0        ; r7 = R7 = G. - C.
244     paddsw        m0, m0
245     movq        I(1), m1        ; save R1
246     paddsw        m0, m7        ; r0 = R0 = G. + C.
247 %endmacro
248
249 ; Column IDCT normalizes and stores final results
250 %macro ColumnIDCT 0
251     BeginIDCT
252     paddsw        m2, OC_8      ; adjust R2 (and R1) for shift
253     paddsw        m1, m1        ; r1 = H. + H.
254     paddsw        m1, m2        ; r1 = R1 = A.. + H.
255     psraw         m2, 4         ; r2 = NR2
256     psubsw        m4, m7        ; r4 = E. = E - G
257     psraw         m1, 4         ; r1 = NR2
258     movq          m3, I(2)      ; r3 = D.
259     paddsw        m7, m7        ; r7 = G + G
260     movq        I(2), m2        ; store NR2 at I2
261     paddsw        m7, m4        ; r7 = G. = E + G
262     movq        I(1), m1        ; store NR1 at I1
263     psubsw        m4, m3        ; r4 = R4 = E. - D.
264     paddsw        m4, OC_8      ; adjust R4 (and R3) for shift
265     paddsw        m3, m3        ; r3 = D. + D.
266     paddsw        m3, m4        ; r3 = R3 = E. + D.
267     psraw         m4, 4         ; r4 = NR4
268     psubsw        m6, m5        ; r6 = R6 = F. - B..
269     psraw         m3, 4         ; r3 = NR3
270     paddsw        m6, OC_8      ; adjust R6 (and R5) for shift
271     paddsw        m5, m5        ; r5 = B.. + B..
272     paddsw        m5, m6        ; r5 = R5 = F. + B..
273     psraw         m6, 4         ; r6 = NR6
274     movq        J(4), m4        ; store NR4 at J4
275     psraw         m5, 4         ; r5 = NR5
276     movq        I(3), m3        ; store NR3 at I3
277     psubsw        m7, m0        ; r7 = R7 = G. - C.
278     paddsw        m7, OC_8      ; adjust R7 (and R0) for shift
279     paddsw        m0, m0        ; r0 = C. + C.
280     paddsw        m0, m7        ; r0 = R0 = G. + C.
281     psraw         m7, 4         ; r7 = NR7
282     movq        J(6), m6        ; store NR6 at J6
283     psraw         m0, 4         ; r0 = NR0
284     movq        J(5), m5        ; store NR5 at J5
285     movq        J(7), m7        ; store NR7 at J7
286     movq        I(0), m0        ; store NR0 at I0
287 %endmacro
288
289 ; Following macro does two 4x4 transposes in place.
290 ;
291 ; At entry (we assume):
292 ;
293 ;   r0 = a3 a2 a1 a0
294 ;   I(1) = b3 b2 b1 b0
295 ;   r2 = c3 c2 c1 c0
296 ;   r3 = d3 d2 d1 d0
297 ;
298 ;   r4 = e3 e2 e1 e0
299 ;   r5 = f3 f2 f1 f0
300 ;   r6 = g3 g2 g1 g0
301 ;   r7 = h3 h2 h1 h0
302 ;
303 ; At exit, we have:
304 ;
305 ;   I(0) = d0 c0 b0 a0
306 ;   I(1) = d1 c1 b1 a1
307 ;   I(2) = d2 c2 b2 a2
308 ;   I(3) = d3 c3 b3 a3
309 ;
310 ;   J(4) = h0 g0 f0 e0
311 ;   J(5) = h1 g1 f1 e1
312 ;   J(6) = h2 g2 f2 e2
313 ;   J(7) = h3 g3 f3 e3
314 ;
315 ;  I(0) I(1) I(2) I(3)  is the transpose of r0 I(1) r2 r3.
316 ;  J(4) J(5) J(6) J(7)  is the transpose of r4 r5 r6 r7.
317 ;
318 ;  Since r1 is free at entry, we calculate the Js first.
319 %macro Transpose 0
320     movq          m1, m4        ; r1 = e3 e2 e1 e0
321     punpcklwd     m4, m5        ; r4 = f1 e1 f0 e0
322     movq        I(0), m0        ; save a3 a2 a1 a0
323     punpckhwd     m1, m5        ; r1 = f3 e3 f2 e2
324     movq          m0, m6        ; r0 = g3 g2 g1 g0
325     punpcklwd     m6, m7        ; r6 = h1 g1 h0 g0
326     movq          m5, m4        ; r5 = f1 e1 f0 e0
327     punpckldq     m4, m6        ; r4 = h0 g0 f0 e0 = R4
328     punpckhdq     m5, m6        ; r5 = h1 g1 f1 e1 = R5
329     movq          m6, m1        ; r6 = f3 e3 f2 e2
330     movq        J(4), m4
331     punpckhwd     m0, m7        ; r0 = h3 g3 h2 g2
332     movq        J(5), m5
333     punpckhdq     m6, m0        ; r6 = h3 g3 f3 e3 = R7
334     movq          m4, I(0)      ; r4 = a3 a2 a1 a0
335     punpckldq     m1, m0        ; r1 = h2 g2 f2 e2 = R6
336     movq          m5, I(1)      ; r5 = b3 b2 b1 b0
337     movq          m0, m4        ; r0 = a3 a2 a1 a0
338     movq        J(7), m6
339     punpcklwd     m0, m5        ; r0 = b1 a1 b0 a0
340     movq        J(6), m1
341     punpckhwd     m4, m5        ; r4 = b3 a3 b2 a2
342     movq          m5, m2        ; r5 = c3 c2 c1 c0
343     punpcklwd     m2, m3        ; r2 = d1 c1 d0 c0
344     movq          m1, m0        ; r1 = b1 a1 b0 a0
345     punpckldq     m0, m2        ; r0 = d0 c0 b0 a0 = R0
346     punpckhdq     m1, m2        ; r1 = d1 c1 b1 a1 = R1
347     movq          m2, m4        ; r2 = b3 a3 b2 a2
348     movq        I(0), m0
349     punpckhwd     m5, m3        ; r5 = d3 c3 d2 c2
350     movq        I(1), m1
351     punpckhdq     m4, m5        ; r4 = d3 c3 b3 a3 = R3
352     punpckldq     m2, m5        ; r2 = d2 c2 b2 a2 = R2
353     movq        I(3), m4
354     movq        I(2), m2
355 %endmacro
356
357 %macro VP3_IDCT_mmx 1
358     ; eax = quantized input
359     ; ebx = dequantizer matrix
360     ; ecx = IDCT constants
361     ;  M(I) = ecx + MaskOffset(0) + I * 8
362     ;  C(I) = ecx + CosineOffset(32) + (I-1) * 8
363     ; edx = output
364     ; r0..r7 = mm0..mm7
365 %define OC_8 [pw_8]
366 %define C(x) [vp3_idct_data+16*(x-1)]
367
368     ; at this point, function has completed dequantization + dezigzag +
369     ; partial transposition; now do the idct itself
370 %define I(x) [%1+16* x     ]
371 %define J(x) [%1+16*(x-4)+8]
372     RowIDCT
373     Transpose
374
375 %define I(x) [%1+16* x   +64]
376 %define J(x) [%1+16*(x-4)+72]
377     RowIDCT
378     Transpose
379
380 %define I(x) [%1+16*x]
381 %define J(x) [%1+16*x]
382     ColumnIDCT
383
384 %define I(x) [%1+16*x+8]
385 %define J(x) [%1+16*x+8]
386     ColumnIDCT
387 %endmacro
388
389 %macro VP3_1D_IDCT_SSE2 0
390     movdqa        m2, I(3)      ; xmm2 = i3
391     movdqa        m6, C(3)      ; xmm6 = c3
392     movdqa        m4, m2        ; xmm4 = i3
393     movdqa        m7, I(5)      ; xmm7 = i5
394     pmulhw        m4, m6        ; xmm4 = c3 * i3 - i3
395     movdqa        m1, C(5)      ; xmm1 = c5
396     pmulhw        m6, m7        ; xmm6 = c3 * i5 - i5
397     movdqa        m5, m1        ; xmm5 = c5
398     pmulhw        m1, m2        ; xmm1 = c5 * i3 - i3
399     movdqa        m3, I(1)      ; xmm3 = i1
400     pmulhw        m5, m7        ; xmm5 = c5 * i5 - i5
401     movdqa        m0, C(1)      ; xmm0 = c1
402     paddw         m4, m2        ; xmm4 = c3 * i3
403     paddw         m6, m7        ; xmm6 = c3 * i5
404     paddw         m2, m1        ; xmm2 = c5 * i3
405     movdqa        m1, I(7)      ; xmm1 = i7
406     paddw         m7, m5        ; xmm7 = c5 * i5
407     movdqa        m5, m0        ; xmm5 = c1
408     pmulhw        m0, m3        ; xmm0 = c1 * i1 - i1
409     paddsw        m4, m7        ; xmm4 = c3 * i3 + c5 * i5 = C
410     pmulhw        m5, m1        ; xmm5 = c1 * i7 - i7
411     movdqa        m7, C(7)      ; xmm7 = c7
412     psubsw        m6, m2        ; xmm6 = c3 * i5 - c5 * i3 = D
413     paddw         m0, m3        ; xmm0 = c1 * i1
414     pmulhw        m3, m7        ; xmm3 = c7 * i1
415     movdqa        m2, I(2)      ; xmm2 = i2
416     pmulhw        m7, m1        ; xmm7 = c7 * i7
417     paddw         m5, m1        ; xmm5 = c1 * i7
418     movdqa        m1, m2        ; xmm1 = i2
419     pmulhw        m2, C(2)      ; xmm2 = i2 * c2 -i2
420     psubsw        m3, m5        ; xmm3 = c7 * i1 - c1 * i7 = B
421     movdqa        m5, I(6)      ; xmm5 = i6
422     paddsw        m0, m7        ; xmm0 = c1 * i1 + c7 * i7 = A
423     movdqa        m7, m5        ; xmm7 = i6
424     psubsw        m0, m4        ; xmm0 = A - C
425     pmulhw        m5, C(2)      ; xmm5 = c2 * i6 - i6
426     paddw         m2, m1        ; xmm2 = i2 * c2
427     pmulhw        m1, C(6)      ; xmm1 = c6 * i2
428     paddsw        m4, m4        ; xmm4 = C + C
429     paddsw        m4, m0        ; xmm4 = A + C = C.
430     psubsw        m3, m6        ; xmm3 = B - D
431     paddw         m5, m7        ; xmm5 = c2 * i6
432     paddsw        m6, m6        ; xmm6 = D + D
433     pmulhw        m7, C(6)      ; xmm7 = c6 * i6
434     paddsw        m6, m3        ; xmm6 = B + D = D.
435     movdqa      I(1), m4        ; Save C. at I(1)
436     psubsw        m1, m5        ; xmm1 = c6 * i2 - c2 * i6 = H
437     movdqa        m4, C(4)      ; xmm4 = C4
438     movdqa        m5, m3        ; xmm5 = B - D
439     pmulhw        m3, m4        ; xmm3 = ( c4 -1 ) * ( B - D )
440     paddsw        m7, m2        ; xmm7 = c2 * i2 + c6 * i6 = G
441     movdqa      I(2), m6        ; save D. at I(2)
442     movdqa        m2, m0        ; xmm2 = A - C
443     movdqa        m6, I(0)      ; xmm6 = i0
444     pmulhw        m0, m4        ; xmm0 = ( c4 - 1 ) * ( A - C ) = A.
445     paddw         m5, m3        ; xmm5 = c4 * ( B - D ) = B.
446     movdqa        m3, I(4)      ; xmm3 = i4
447     psubsw        m5, m1        ; xmm5 = B. - H = B..
448     paddw         m2, m0        ; xmm2 = c4 * ( A - C) = A.
449     psubsw        m6, m3        ; xmm6 = i0 - i4
450     movdqa        m0, m6        ; xmm0 = i0 - i4
451     pmulhw        m6, m4        ; xmm6 = (c4 - 1) * (i0 - i4) = F
452     paddsw        m3, m3        ; xmm3 = i4 + i4
453     paddsw        m1, m1        ; xmm1 = H + H
454     paddsw        m3, m0        ; xmm3 = i0 + i4
455     paddsw        m1, m5        ; xmm1 = B. + H = H.
456     pmulhw        m4, m3        ; xmm4 = ( c4 - 1 ) * ( i0 + i4 )
457     paddw         m6, m0        ; xmm6 = c4 * ( i0 - i4 )
458     psubsw        m6, m2        ; xmm6 = F - A. = F.
459     paddsw        m2, m2        ; xmm2 = A. + A.
460     movdqa        m0, I(1)      ; Load        C. from I(1)
461     paddsw        m2, m6        ; xmm2 = F + A. = A..
462     paddw         m4, m3        ; xmm4 = c4 * ( i0 + i4 ) = 3
463     psubsw        m2, m1        ; xmm2 = A.. - H. = R2
464     ADD(m2)                     ; Adjust R2 and R1 before shifting
465     paddsw        m1, m1        ; xmm1 = H. + H.
466     paddsw        m1, m2        ; xmm1 = A.. + H. = R1
467     SHIFT(m2)                   ; xmm2 = op2
468     psubsw        m4, m7        ; xmm4 = E - G = E.
469     SHIFT(m1)                   ; xmm1 = op1
470     movdqa        m3, I(2)      ; Load D. from I(2)
471     paddsw        m7, m7        ; xmm7 = G + G
472     paddsw        m7, m4        ; xmm7 = E + G = G.
473     psubsw        m4, m3        ; xmm4 = E. - D. = R4
474     ADD(m4)                     ; Adjust R4 and R3 before shifting
475     paddsw        m3, m3        ; xmm3 = D. + D.
476     paddsw        m3, m4        ; xmm3 = E. + D. = R3
477     SHIFT(m4)                   ; xmm4 = op4
478     psubsw        m6, m5        ; xmm6 = F. - B..= R6
479     SHIFT(m3)                   ; xmm3 = op3
480     ADD(m6)                     ; Adjust R6 and R5 before shifting
481     paddsw        m5, m5        ; xmm5 = B.. + B..
482     paddsw        m5, m6        ; xmm5 = F. + B.. = R5
483     SHIFT(m6)                   ; xmm6 = op6
484     SHIFT(m5)                   ; xmm5 = op5
485     psubsw        m7, m0        ; xmm7 = G. - C. = R7
486     ADD(m7)                     ; Adjust R7 and R0 before shifting
487     paddsw        m0, m0        ; xmm0 = C. + C.
488     paddsw        m0, m7        ; xmm0 = G. + C.
489     SHIFT(m7)                   ; xmm7 = op7
490     SHIFT(m0)                   ; xmm0 = op0
491 %endmacro
492
493 %macro PUT_BLOCK 8
494     movdqa      O(0), m%1
495     movdqa      O(1), m%2
496     movdqa      O(2), m%3
497     movdqa      O(3), m%4
498     movdqa      O(4), m%5
499     movdqa      O(5), m%6
500     movdqa      O(6), m%7
501     movdqa      O(7), m%8
502 %endmacro
503
504 %macro VP3_IDCT_sse2 1
505 %define I(x) [%1+16*x]
506 %define O(x) [%1+16*x]
507 %define C(x) [vp3_idct_data+16*(x-1)]
508 %define SHIFT(x)
509 %define ADD(x)
510         VP3_1D_IDCT_SSE2
511 %if ARCH_X86_64
512         TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8
513 %else
514         TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [%1], [%1+16]
515 %endif
516         PUT_BLOCK 0, 1, 2, 3, 4, 5, 6, 7
517
518 %define SHIFT(x) psraw  x, 4
519 %define ADD(x)   paddsw x, [pw_8]
520         VP3_1D_IDCT_SSE2
521         PUT_BLOCK 0, 1, 2, 3, 4, 5, 6, 7
522 %endmacro
523
524 %macro vp3_idct_funcs 1
525 cglobal vp3_idct_put_%1, 3, 4, 9
526     VP3_IDCT_%1   r2
527
528     movsxdifnidn  r1, r1d
529     mova          m4, [pb_80]
530     lea           r3, [r1*3]
531 %assign %%i 0
532 %rep 16/mmsize
533     mova          m0, [r2+mmsize*0+%%i]
534     mova          m1, [r2+mmsize*2+%%i]
535     mova          m2, [r2+mmsize*4+%%i]
536     mova          m3, [r2+mmsize*6+%%i]
537     packsswb      m0, [r2+mmsize*1+%%i]
538     packsswb      m1, [r2+mmsize*3+%%i]
539     packsswb      m2, [r2+mmsize*5+%%i]
540     packsswb      m3, [r2+mmsize*7+%%i]
541     paddb         m0, m4
542     paddb         m1, m4
543     paddb         m2, m4
544     paddb         m3, m4
545     movq   [r0     ], m0
546 %if mmsize == 8
547     movq   [r0+r1  ], m1
548     movq   [r0+r1*2], m2
549     movq   [r0+r3  ], m3
550 %else
551     movhps [r0+r1  ], m0
552     movq   [r0+r1*2], m1
553     movhps [r0+r3  ], m1
554 %endif
555 %if %%i == 0
556     lea           r0, [r0+r1*4]
557 %endif
558 %if mmsize == 16
559     movq   [r0     ], m2
560     movhps [r0+r1  ], m2
561     movq   [r0+r1*2], m3
562     movhps [r0+r3  ], m3
563 %endif
564 %assign %%i %%i+64
565 %endrep
566     RET
567
568 cglobal vp3_idct_add_%1, 3, 4, 9
569     VP3_IDCT_%1   r2
570
571     mov           r3, 4
572     pxor          m4, m4
573     movsxdifnidn  r1, r1d
574 .loop:
575     movq          m0, [r0]
576     movq          m1, [r0+r1]
577 %if mmsize == 8
578     mova          m2, m0
579     mova          m3, m1
580 %endif
581     punpcklbw     m0, m4
582     punpcklbw     m1, m4
583 %if mmsize == 8
584     punpckhbw     m2, m4
585     punpckhbw     m3, m4
586 %endif
587     paddsw        m0, [r2+ 0]
588     paddsw        m1, [r2+16]
589 %if mmsize == 8
590     paddsw        m2, [r2+ 8]
591     paddsw        m3, [r2+24]
592     packuswb      m0, m2
593     packuswb      m1, m3
594 %else ; mmsize == 16
595     packuswb      m0, m1
596 %endif
597     movq     [r0   ], m0
598 %if mmsize == 8
599     movq     [r0+r1], m1
600 %else ; mmsize == 16
601     movhps   [r0+r1], m0
602 %endif
603     lea           r0, [r0+r1*2]
604     add           r2, 32
605     dec           r3
606     jg .loop
607     RET
608 %endmacro
609
610 INIT_MMX
611 vp3_idct_funcs mmx
612 INIT_XMM
613 vp3_idct_funcs sse2
614
615 %macro DC_ADD 0
616     movq          m2, [r0     ]
617     movq          m3, [r0+r1  ]
618     paddusb       m2, m0
619     movq          m4, [r0+r1*2]
620     paddusb       m3, m0
621     movq          m5, [r0+r3  ]
622     paddusb       m4, m0
623     paddusb       m5, m0
624     psubusb       m2, m1
625     psubusb       m3, m1
626     movq   [r0     ], m2
627     psubusb       m4, m1
628     movq   [r0+r1  ], m3
629     psubusb       m5, m1
630     movq   [r0+r1*2], m4
631     movq   [r0+r3  ], m5
632 %endmacro
633
634 INIT_MMX
635 cglobal vp3_idct_dc_add_mmx2, 3, 4
636 %if ARCH_X86_64
637     movsxd        r1, r1d
638 %endif
639     lea           r3, [r1*3]
640     movsx         r2, word [r2]
641     add           r2, 15
642     sar           r2, 5
643     movd          m0, r2d
644     pshufw        m0, m0, 0x0
645     pxor          m1, m1
646     psubw         m1, m0
647     packuswb      m0, m0
648     packuswb      m1, m1
649     DC_ADD
650     lea           r0, [r0+r1*4]
651     DC_ADD
652     RET