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