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