]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/vp3dsp.asm
utvideodec: Support UQRA and UQRG
[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 "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
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 mmxext
106 cglobal vp3_v_loop_filter, 3, 4
107     mov           r3, r1
108     neg           r1
109     movq          m6, [r0+r1*2]
110     movq          m4, [r0+r1  ]
111     movq          m2, [r0     ]
112     movq          m1, [r0+r3  ]
113
114     VP3_LOOP_FILTER
115
116     movq     [r0+r1], m4
117     movq     [r0   ], m3
118     RET
119
120 cglobal vp3_h_loop_filter, 3, 4
121     lea           r3, [r1*3]
122
123     movd          m6, [r0     -2]
124     movd          m4, [r0+r1  -2]
125     movd          m2, [r0+r1*2-2]
126     movd          m1, [r0+r3  -2]
127     lea           r0, [r0+r1*4  ]
128     punpcklbw     m6, [r0     -2]
129     punpcklbw     m4, [r0+r1  -2]
130     punpcklbw     m2, [r0+r1*2-2]
131     punpcklbw     m1, [r0+r3  -2]
132     sub           r0, r3
133     sub           r0, r1
134
135     TRANSPOSE4x4B  6, 4, 2, 1, 0
136     VP3_LOOP_FILTER
137     SBUTTERFLY    bw, 4, 3, 5
138
139     STORE_4_WORDS m4
140     lea           r0, [r0+r1*4  ]
141     STORE_4_WORDS m3
142     RET
143
144 ; from original comments: The Macro does IDct on 4 1-D Dcts
145 %macro BeginIDCT 0
146     movq          m2, I(3)
147     movq          m6, C(3)
148     movq          m4, m2
149     movq          m7, J(5)
150     pmulhw        m4, m6        ; r4 = c3*i3 - i3
151     movq          m1, C(5)
152     pmulhw        m6, m7        ; r6 = c3*i5 - i5
153     movq          m5, m1
154     pmulhw        m1, m2        ; r1 = c5*i3 - i3
155     movq          m3, I(1)
156     pmulhw        m5, m7        ; r5 = c5*i5 - i5
157     movq          m0, C(1)
158     paddw         m4, m2        ; r4 = c3*i3
159     paddw         m6, m7        ; r6 = c3*i5
160     paddw         m2, m1        ; r2 = c5*i3
161     movq          m1, J(7)
162     paddw         m7, m5        ; r7 = c5*i5
163     movq          m5, m0        ; r5 = c1
164     pmulhw        m0, m3        ; r0 = c1*i1 - i1
165     paddsw        m4, m7        ; r4 = C = c3*i3 + c5*i5
166     pmulhw        m5, m1        ; r5 = c1*i7 - i7
167     movq          m7, C(7)
168     psubsw        m6, m2        ; r6 = D = c3*i5 - c5*i3
169     paddw         m0, m3        ; r0 = c1*i1
170     pmulhw        m3, m7        ; r3 = c7*i1
171     movq          m2, I(2)
172     pmulhw        m7, m1        ; r7 = c7*i7
173     paddw         m5, m1        ; r5 = c1*i7
174     movq          m1, m2        ; r1 = i2
175     pmulhw        m2, C(2)      ; r2 = c2*i2 - i2
176     psubsw        m3, m5        ; r3 = B = c7*i1 - c1*i7
177     movq          m5, J(6)
178     paddsw        m0, m7        ; r0 = A = c1*i1 + c7*i7
179     movq          m7, m5        ; r7 = i6
180     psubsw        m0, m4        ; r0 = A - C
181     pmulhw        m5, C(2)      ; r5 = c2*i6 - i6
182     paddw         m2, m1        ; r2 = c2*i2
183     pmulhw        m1, C(6)      ; r1 = c6*i2
184     paddsw        m4, m4        ; r4 = C + C
185     paddsw        m4, m0        ; r4 = C. = A + C
186     psubsw        m3, m6        ; r3 = B - D
187     paddw         m5, m7        ; r5 = c2*i6
188     paddsw        m6, m6        ; r6 = D + D
189     pmulhw        m7, C(6)      ; r7 = c6*i6
190     paddsw        m6, m3        ; r6 = D. = B + D
191     movq        I(1), m4        ; save C. at I(1)
192     psubsw        m1, m5        ; r1 = H = c6*i2 - c2*i6
193     movq          m4, C(4)
194     movq          m5, m3        ; r5 = B - D
195     pmulhw        m3, m4        ; r3 = (c4 - 1) * (B - D)
196     paddsw        m7, m2        ; r3 = (c4 - 1) * (B - D)
197     movq        I(2), m6        ; save D. at I(2)
198     movq          m2, m0        ; r2 = A - C
199     movq          m6, I(0)
200     pmulhw        m0, m4        ; r0 = (c4 - 1) * (A - C)
201     paddw         m5, m3        ; r5 = B. = c4 * (B - D)
202     movq          m3, J(4)
203     psubsw        m5, m1        ; r5 = B.. = B. - H
204     paddw         m2, m0        ; r0 = A. = c4 * (A - C)
205     psubsw        m6, m3        ; r6 = i0 - i4
206     movq          m0, m6
207     pmulhw        m6, m4        ; r6 = (c4 - 1) * (i0 - i4)
208     paddsw        m3, m3        ; r3 = i4 + i4
209     paddsw        m1, m1        ; r1 = H + H
210     paddsw        m3, m0        ; r3 = i0 + i4
211     paddsw        m1, m5        ; r1 = H. = B + H
212     pmulhw        m4, m3        ; r4 = (c4 - 1) * (i0 + i4)
213     paddsw        m6, m0        ; r6 = F = c4 * (i0 - i4)
214     psubsw        m6, m2        ; r6 = F. = F - A.
215     paddsw        m2, m2        ; r2 = A. + A.
216     movq          m0, I(1)      ; r0 = C.
217     paddsw        m2, m6        ; r2 = A.. = F + A.
218     paddw         m4, m3        ; r4 = E = c4 * (i0 + i4)
219     psubsw        m2, m1        ; r2 = R2 = A.. - H.
220 %endmacro
221
222 ; RowIDCT gets ready to transpose
223 %macro RowIDCT 0
224     BeginIDCT
225     movq          m3, I(2)      ; r3 = D.
226     psubsw        m4, m7        ; r4 = E. = E - G
227     paddsw        m1, m1        ; r1 = H. + H.
228     paddsw        m7, m7        ; r7 = G + G
229     paddsw        m1, m2        ; r1 = R1 = A.. + H.
230     paddsw        m7, m4        ; r1 = R1 = A.. + H.
231     psubsw        m4, m3        ; r4 = R4 = E. - D.
232     paddsw        m3, m3
233     psubsw        m6, m5        ; r6 = R6 = F. - B..
234     paddsw        m5, m5
235     paddsw        m3, m4        ; r3 = R3 = E. + D.
236     paddsw        m5, m6        ; r5 = R5 = F. + B..
237     psubsw        m7, m0        ; r7 = R7 = G. - C.
238     paddsw        m0, m0
239     movq        I(1), m1        ; save R1
240     paddsw        m0, m7        ; r0 = R0 = G. + C.
241 %endmacro
242
243 ; Column IDCT normalizes and stores final results
244 %macro ColumnIDCT 0
245     BeginIDCT
246     paddsw        m2, OC_8      ; adjust R2 (and R1) for shift
247     paddsw        m1, m1        ; r1 = H. + H.
248     paddsw        m1, m2        ; r1 = R1 = A.. + H.
249     psraw         m2, 4         ; r2 = NR2
250     psubsw        m4, m7        ; r4 = E. = E - G
251     psraw         m1, 4         ; r1 = NR2
252     movq          m3, I(2)      ; r3 = D.
253     paddsw        m7, m7        ; r7 = G + G
254     movq        I(2), m2        ; store NR2 at I2
255     paddsw        m7, m4        ; r7 = G. = E + G
256     movq        I(1), m1        ; store NR1 at I1
257     psubsw        m4, m3        ; r4 = R4 = E. - D.
258     paddsw        m4, OC_8      ; adjust R4 (and R3) for shift
259     paddsw        m3, m3        ; r3 = D. + D.
260     paddsw        m3, m4        ; r3 = R3 = E. + D.
261     psraw         m4, 4         ; r4 = NR4
262     psubsw        m6, m5        ; r6 = R6 = F. - B..
263     psraw         m3, 4         ; r3 = NR3
264     paddsw        m6, OC_8      ; adjust R6 (and R5) for shift
265     paddsw        m5, m5        ; r5 = B.. + B..
266     paddsw        m5, m6        ; r5 = R5 = F. + B..
267     psraw         m6, 4         ; r6 = NR6
268     movq        J(4), m4        ; store NR4 at J4
269     psraw         m5, 4         ; r5 = NR5
270     movq        I(3), m3        ; store NR3 at I3
271     psubsw        m7, m0        ; r7 = R7 = G. - C.
272     paddsw        m7, OC_8      ; adjust R7 (and R0) for shift
273     paddsw        m0, m0        ; r0 = C. + C.
274     paddsw        m0, m7        ; r0 = R0 = G. + C.
275     psraw         m7, 4         ; r7 = NR7
276     movq        J(6), m6        ; store NR6 at J6
277     psraw         m0, 4         ; r0 = NR0
278     movq        J(5), m5        ; store NR5 at J5
279     movq        J(7), m7        ; store NR7 at J7
280     movq        I(0), m0        ; store NR0 at I0
281 %endmacro
282
283 ; Following macro does two 4x4 transposes in place.
284 ;
285 ; At entry (we assume):
286 ;
287 ;   r0 = a3 a2 a1 a0
288 ;   I(1) = b3 b2 b1 b0
289 ;   r2 = c3 c2 c1 c0
290 ;   r3 = d3 d2 d1 d0
291 ;
292 ;   r4 = e3 e2 e1 e0
293 ;   r5 = f3 f2 f1 f0
294 ;   r6 = g3 g2 g1 g0
295 ;   r7 = h3 h2 h1 h0
296 ;
297 ; At exit, we have:
298 ;
299 ;   I(0) = d0 c0 b0 a0
300 ;   I(1) = d1 c1 b1 a1
301 ;   I(2) = d2 c2 b2 a2
302 ;   I(3) = d3 c3 b3 a3
303 ;
304 ;   J(4) = h0 g0 f0 e0
305 ;   J(5) = h1 g1 f1 e1
306 ;   J(6) = h2 g2 f2 e2
307 ;   J(7) = h3 g3 f3 e3
308 ;
309 ;  I(0) I(1) I(2) I(3)  is the transpose of r0 I(1) r2 r3.
310 ;  J(4) J(5) J(6) J(7)  is the transpose of r4 r5 r6 r7.
311 ;
312 ;  Since r1 is free at entry, we calculate the Js first.
313 %macro Transpose 0
314     movq          m1, m4        ; r1 = e3 e2 e1 e0
315     punpcklwd     m4, m5        ; r4 = f1 e1 f0 e0
316     movq        I(0), m0        ; save a3 a2 a1 a0
317     punpckhwd     m1, m5        ; r1 = f3 e3 f2 e2
318     movq          m0, m6        ; r0 = g3 g2 g1 g0
319     punpcklwd     m6, m7        ; r6 = h1 g1 h0 g0
320     movq          m5, m4        ; r5 = f1 e1 f0 e0
321     punpckldq     m4, m6        ; r4 = h0 g0 f0 e0 = R4
322     punpckhdq     m5, m6        ; r5 = h1 g1 f1 e1 = R5
323     movq          m6, m1        ; r6 = f3 e3 f2 e2
324     movq        J(4), m4
325     punpckhwd     m0, m7        ; r0 = h3 g3 h2 g2
326     movq        J(5), m5
327     punpckhdq     m6, m0        ; r6 = h3 g3 f3 e3 = R7
328     movq          m4, I(0)      ; r4 = a3 a2 a1 a0
329     punpckldq     m1, m0        ; r1 = h2 g2 f2 e2 = R6
330     movq          m5, I(1)      ; r5 = b3 b2 b1 b0
331     movq          m0, m4        ; r0 = a3 a2 a1 a0
332     movq        J(7), m6
333     punpcklwd     m0, m5        ; r0 = b1 a1 b0 a0
334     movq        J(6), m1
335     punpckhwd     m4, m5        ; r4 = b3 a3 b2 a2
336     movq          m5, m2        ; r5 = c3 c2 c1 c0
337     punpcklwd     m2, m3        ; r2 = d1 c1 d0 c0
338     movq          m1, m0        ; r1 = b1 a1 b0 a0
339     punpckldq     m0, m2        ; r0 = d0 c0 b0 a0 = R0
340     punpckhdq     m1, m2        ; r1 = d1 c1 b1 a1 = R1
341     movq          m2, m4        ; r2 = b3 a3 b2 a2
342     movq        I(0), m0
343     punpckhwd     m5, m3        ; r5 = d3 c3 d2 c2
344     movq        I(1), m1
345     punpckhdq     m4, m5        ; r4 = d3 c3 b3 a3 = R3
346     punpckldq     m2, m5        ; r2 = d2 c2 b2 a2 = R2
347     movq        I(3), m4
348     movq        I(2), m2
349 %endmacro
350
351 %macro VP3_1D_IDCT_SSE2 0
352     movdqa        m2, I(3)      ; xmm2 = i3
353     movdqa        m6, C(3)      ; xmm6 = c3
354     movdqa        m4, m2        ; xmm4 = i3
355     movdqa        m7, I(5)      ; xmm7 = i5
356     pmulhw        m4, m6        ; xmm4 = c3 * i3 - i3
357     movdqa        m1, C(5)      ; xmm1 = c5
358     pmulhw        m6, m7        ; xmm6 = c3 * i5 - i5
359     movdqa        m5, m1        ; xmm5 = c5
360     pmulhw        m1, m2        ; xmm1 = c5 * i3 - i3
361     movdqa        m3, I(1)      ; xmm3 = i1
362     pmulhw        m5, m7        ; xmm5 = c5 * i5 - i5
363     movdqa        m0, C(1)      ; xmm0 = c1
364     paddw         m4, m2        ; xmm4 = c3 * i3
365     paddw         m6, m7        ; xmm6 = c3 * i5
366     paddw         m2, m1        ; xmm2 = c5 * i3
367     movdqa        m1, I(7)      ; xmm1 = i7
368     paddw         m7, m5        ; xmm7 = c5 * i5
369     movdqa        m5, m0        ; xmm5 = c1
370     pmulhw        m0, m3        ; xmm0 = c1 * i1 - i1
371     paddsw        m4, m7        ; xmm4 = c3 * i3 + c5 * i5 = C
372     pmulhw        m5, m1        ; xmm5 = c1 * i7 - i7
373     movdqa        m7, C(7)      ; xmm7 = c7
374     psubsw        m6, m2        ; xmm6 = c3 * i5 - c5 * i3 = D
375     paddw         m0, m3        ; xmm0 = c1 * i1
376     pmulhw        m3, m7        ; xmm3 = c7 * i1
377     movdqa        m2, I(2)      ; xmm2 = i2
378     pmulhw        m7, m1        ; xmm7 = c7 * i7
379     paddw         m5, m1        ; xmm5 = c1 * i7
380     movdqa        m1, m2        ; xmm1 = i2
381     pmulhw        m2, C(2)      ; xmm2 = i2 * c2 -i2
382     psubsw        m3, m5        ; xmm3 = c7 * i1 - c1 * i7 = B
383     movdqa        m5, I(6)      ; xmm5 = i6
384     paddsw        m0, m7        ; xmm0 = c1 * i1 + c7 * i7 = A
385     movdqa        m7, m5        ; xmm7 = i6
386     psubsw        m0, m4        ; xmm0 = A - C
387     pmulhw        m5, C(2)      ; xmm5 = c2 * i6 - i6
388     paddw         m2, m1        ; xmm2 = i2 * c2
389     pmulhw        m1, C(6)      ; xmm1 = c6 * i2
390     paddsw        m4, m4        ; xmm4 = C + C
391     paddsw        m4, m0        ; xmm4 = A + C = C.
392     psubsw        m3, m6        ; xmm3 = B - D
393     paddw         m5, m7        ; xmm5 = c2 * i6
394     paddsw        m6, m6        ; xmm6 = D + D
395     pmulhw        m7, C(6)      ; xmm7 = c6 * i6
396     paddsw        m6, m3        ; xmm6 = B + D = D.
397     movdqa      I(1), m4        ; Save C. at I(1)
398     psubsw        m1, m5        ; xmm1 = c6 * i2 - c2 * i6 = H
399     movdqa        m4, C(4)      ; xmm4 = C4
400     movdqa        m5, m3        ; xmm5 = B - D
401     pmulhw        m3, m4        ; xmm3 = ( c4 -1 ) * ( B - D )
402     paddsw        m7, m2        ; xmm7 = c2 * i2 + c6 * i6 = G
403     movdqa      I(2), m6        ; save D. at I(2)
404     movdqa        m2, m0        ; xmm2 = A - C
405     movdqa        m6, I(0)      ; xmm6 = i0
406     pmulhw        m0, m4        ; xmm0 = ( c4 - 1 ) * ( A - C ) = A.
407     paddw         m5, m3        ; xmm5 = c4 * ( B - D ) = B.
408     movdqa        m3, I(4)      ; xmm3 = i4
409     psubsw        m5, m1        ; xmm5 = B. - H = B..
410     paddw         m2, m0        ; xmm2 = c4 * ( A - C) = A.
411     psubsw        m6, m3        ; xmm6 = i0 - i4
412     movdqa        m0, m6        ; xmm0 = i0 - i4
413     pmulhw        m6, m4        ; xmm6 = (c4 - 1) * (i0 - i4) = F
414     paddsw        m3, m3        ; xmm3 = i4 + i4
415     paddsw        m1, m1        ; xmm1 = H + H
416     paddsw        m3, m0        ; xmm3 = i0 + i4
417     paddsw        m1, m5        ; xmm1 = B. + H = H.
418     pmulhw        m4, m3        ; xmm4 = ( c4 - 1 ) * ( i0 + i4 )
419     paddw         m6, m0        ; xmm6 = c4 * ( i0 - i4 )
420     psubsw        m6, m2        ; xmm6 = F - A. = F.
421     paddsw        m2, m2        ; xmm2 = A. + A.
422     movdqa        m0, I(1)      ; Load        C. from I(1)
423     paddsw        m2, m6        ; xmm2 = F + A. = A..
424     paddw         m4, m3        ; xmm4 = c4 * ( i0 + i4 ) = 3
425     psubsw        m2, m1        ; xmm2 = A.. - H. = R2
426     ADD(m2)                     ; Adjust R2 and R1 before shifting
427     paddsw        m1, m1        ; xmm1 = H. + H.
428     paddsw        m1, m2        ; xmm1 = A.. + H. = R1
429     SHIFT(m2)                   ; xmm2 = op2
430     psubsw        m4, m7        ; xmm4 = E - G = E.
431     SHIFT(m1)                   ; xmm1 = op1
432     movdqa        m3, I(2)      ; Load D. from I(2)
433     paddsw        m7, m7        ; xmm7 = G + G
434     paddsw        m7, m4        ; xmm7 = E + G = G.
435     psubsw        m4, m3        ; xmm4 = E. - D. = R4
436     ADD(m4)                     ; Adjust R4 and R3 before shifting
437     paddsw        m3, m3        ; xmm3 = D. + D.
438     paddsw        m3, m4        ; xmm3 = E. + D. = R3
439     SHIFT(m4)                   ; xmm4 = op4
440     psubsw        m6, m5        ; xmm6 = F. - B..= R6
441     SHIFT(m3)                   ; xmm3 = op3
442     ADD(m6)                     ; Adjust R6 and R5 before shifting
443     paddsw        m5, m5        ; xmm5 = B.. + B..
444     paddsw        m5, m6        ; xmm5 = F. + B.. = R5
445     SHIFT(m6)                   ; xmm6 = op6
446     SHIFT(m5)                   ; xmm5 = op5
447     psubsw        m7, m0        ; xmm7 = G. - C. = R7
448     ADD(m7)                     ; Adjust R7 and R0 before shifting
449     paddsw        m0, m0        ; xmm0 = C. + C.
450     paddsw        m0, m7        ; xmm0 = G. + C.
451     SHIFT(m7)                   ; xmm7 = op7
452     SHIFT(m0)                   ; xmm0 = op0
453 %endmacro
454
455 %macro PUT_BLOCK 8
456     movdqa      O(0), m%1
457     movdqa      O(1), m%2
458     movdqa      O(2), m%3
459     movdqa      O(3), m%4
460     movdqa      O(4), m%5
461     movdqa      O(5), m%6
462     movdqa      O(6), m%7
463     movdqa      O(7), m%8
464 %endmacro
465
466 %macro VP3_IDCT 1
467 %if mmsize == 16
468 %define I(x) [%1+16*x]
469 %define O(x) [%1+16*x]
470 %define C(x) [vp3_idct_data+16*(x-1)]
471 %define SHIFT(x)
472 %define ADD(x)
473         VP3_1D_IDCT_SSE2
474 %if ARCH_X86_64
475         TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8
476 %else
477         TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [%1], [%1+16]
478 %endif
479         PUT_BLOCK 0, 1, 2, 3, 4, 5, 6, 7
480
481 %define SHIFT(x) psraw  x, 4
482 %define ADD(x)   paddsw x, [pw_8]
483         VP3_1D_IDCT_SSE2
484         PUT_BLOCK 0, 1, 2, 3, 4, 5, 6, 7
485 %else ; mmsize == 8
486     ; eax = quantized input
487     ; ebx = dequantizer matrix
488     ; ecx = IDCT constants
489     ;  M(I) = ecx + MaskOffset(0) + I * 8
490     ;  C(I) = ecx + CosineOffset(32) + (I-1) * 8
491     ; edx = output
492     ; r0..r7 = mm0..mm7
493 %define OC_8 [pw_8]
494 %define C(x) [vp3_idct_data+16*(x-1)]
495
496     ; at this point, function has completed dequantization + dezigzag +
497     ; partial transposition; now do the idct itself
498 %define I(x) [%1+16*x]
499 %define J(x) [%1+16*x]
500     RowIDCT
501     Transpose
502
503 %define I(x) [%1+16*x+8]
504 %define J(x) [%1+16*x+8]
505     RowIDCT
506     Transpose
507
508 %define I(x) [%1+16* x]
509 %define J(x) [%1+16*(x-4)+8]
510     ColumnIDCT
511
512 %define I(x) [%1+16* x   +64]
513 %define J(x) [%1+16*(x-4)+72]
514     ColumnIDCT
515 %endif ; mmsize == 16/8
516 %endmacro
517
518 %macro vp3_idct_funcs 0
519 cglobal vp3_idct_put, 3, 4, 9
520     VP3_IDCT      r2
521
522     mova          m4, [pb_80]
523     lea           r3, [r1*3]
524 %assign %%i 0
525 %rep 16/mmsize
526     mova          m0, [r2+mmsize*0+%%i]
527     mova          m1, [r2+mmsize*2+%%i]
528     mova          m2, [r2+mmsize*4+%%i]
529     mova          m3, [r2+mmsize*6+%%i]
530 %if mmsize == 8
531     packsswb      m0, [r2+mmsize*8+%%i]
532     packsswb      m1, [r2+mmsize*10+%%i]
533     packsswb      m2, [r2+mmsize*12+%%i]
534     packsswb      m3, [r2+mmsize*14+%%i]
535 %else
536     packsswb      m0, [r2+mmsize*1+%%i]
537     packsswb      m1, [r2+mmsize*3+%%i]
538     packsswb      m2, [r2+mmsize*5+%%i]
539     packsswb      m3, [r2+mmsize*7+%%i]
540 %endif
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+8
565 %endrep
566
567     pxor          m0, m0
568 %assign %%offset 0
569 %rep 128/mmsize
570     mova [r2+%%offset], m0
571 %assign %%offset %%offset+mmsize
572 %endrep
573     RET
574
575 cglobal vp3_idct_add, 3, 4, 9
576     VP3_IDCT      r2
577
578     lea           r3, [r1*3]
579     pxor          m4, m4
580 %if mmsize == 16
581 %assign %%i 0
582 %rep 2
583     movq          m0, [r0]
584     movq          m1, [r0+r1]
585     movq          m2, [r0+r1*2]
586     movq          m3, [r0+r3]
587     punpcklbw     m0, m4
588     punpcklbw     m1, m4
589     punpcklbw     m2, m4
590     punpcklbw     m3, m4
591     paddsw        m0, [r2+ 0+%%i]
592     paddsw        m1, [r2+16+%%i]
593     paddsw        m2, [r2+32+%%i]
594     paddsw        m3, [r2+48+%%i]
595     packuswb      m0, m1
596     packuswb      m2, m3
597     movq   [r0     ], m0
598     movhps [r0+r1  ], m0
599     movq   [r0+r1*2], m2
600     movhps [r0+r3  ], m2
601 %if %%i == 0
602     lea           r0, [r0+r1*4]
603 %endif
604 %assign %%i %%i+64
605 %endrep
606 %else
607 %assign %%i 0
608 %rep 2
609     movq          m0, [r0]
610     movq          m1, [r0+r1]
611     movq          m2, [r0+r1*2]
612     movq          m3, [r0+r3]
613     movq          m5, m0
614     movq          m6, m1
615     movq          m7, m2
616     punpcklbw     m0, m4
617     punpcklbw     m1, m4
618     punpcklbw     m2, m4
619     punpckhbw     m5, m4
620     punpckhbw     m6, m4
621     punpckhbw     m7, m4
622     paddsw        m0, [r2+ 0+%%i]
623     paddsw        m1, [r2+16+%%i]
624     paddsw        m2, [r2+32+%%i]
625     paddsw        m5, [r2+64+%%i]
626     paddsw        m6, [r2+80+%%i]
627     paddsw        m7, [r2+96+%%i]
628     packuswb      m0, m5
629     movq          m5, m3
630     punpcklbw     m3, m4
631     punpckhbw     m5, m4
632     packuswb      m1, m6
633     paddsw        m3, [r2+48+%%i]
634     paddsw        m5, [r2+112+%%i]
635     packuswb      m2, m7
636     packuswb      m3, m5
637     movq   [r0     ], m0
638     movq   [r0+r1  ], m1
639     movq   [r0+r1*2], m2
640     movq   [r0+r3  ], m3
641 %if %%i == 0
642     lea           r0, [r0+r1*4]
643 %endif
644 %assign %%i %%i+8
645 %endrep
646 %endif
647 %assign %%i 0
648 %rep 128/mmsize
649     mova    [r2+%%i], m4
650 %assign %%i %%i+mmsize
651 %endrep
652     RET
653 %endmacro
654
655 %if ARCH_X86_32
656 INIT_MMX mmx
657 vp3_idct_funcs
658 %endif
659
660 INIT_XMM sse2
661 vp3_idct_funcs
662
663 %macro DC_ADD 0
664     movq          m2, [r0     ]
665     movq          m3, [r0+r1  ]
666     paddusb       m2, m0
667     movq          m4, [r0+r1*2]
668     paddusb       m3, m0
669     movq          m5, [r0+r2  ]
670     paddusb       m4, m0
671     paddusb       m5, m0
672     psubusb       m2, m1
673     psubusb       m3, m1
674     movq   [r0     ], m2
675     psubusb       m4, m1
676     movq   [r0+r1  ], m3
677     psubusb       m5, m1
678     movq   [r0+r1*2], m4
679     movq   [r0+r2  ], m5
680 %endmacro
681
682 INIT_MMX mmxext
683 cglobal vp3_idct_dc_add, 3, 4
684     movsx         r3, word [r2]
685     mov    word [r2], 0
686     lea           r2, [r1*3]
687     add           r3, 15
688     sar           r3, 5
689     movd          m0, r3d
690     pshufw        m0, m0, 0x0
691     pxor          m1, m1
692     psubw         m1, m0
693     packuswb      m0, m0
694     packuswb      m1, m1
695     DC_ADD
696     lea           r0, [r0+r1*4]
697     DC_ADD
698     RET