1 ;******************************************************************************
2 ;* MMX/SSE2-optimized functions for the VP3 decoder
3 ;* Copyright (c) 2007 Aurelien Jacobs <aurel@gnuage.org>
5 ;* This file is part of Libav.
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.
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.
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 ;******************************************************************************
22 %include "libavutil/x86/x86util.asm"
24 ; MMX-optimized functions cribbed from the original VP3 source code.
28 vp3_idct_data: times
8 dw 64277
47 ; this is off by one or two for some cases when filter_limit is greater than 63
48 ; in: p0 in mm6, p1 in mm4, p2 in mm2, p3 in mm1
49 ; out: p1 in mm4, p2 in mm3
50 %macro VP3_LOOP_FILTER
0
52 pand m6
, [pb_7
] ; p0&7
54 pand m7
, [pb_1F
] ; p0>>3
57 pand m2
, [pb_1
] ; (p2^p1)&1
60 paddb m2
, m5
; 3*(p2^p1)&1
61 paddb m2
, m6
; extra bits lost in shifts
63 pxor m1
, m0
; 255 - p3
64 pavgb m1
, m2
; (256 - p3 + extrabits) >> 1
65 pxor m0
, m4
; 255 - p1
66 pavgb m0
, m3
; (256 + p2-p1) >> 1
68 pavgb m1
, m0
; 128+2+( p2-p1 - p3) >> 2
69 pavgb m1
, m0
; 128+1+(3*(p2-p1) - p3) >> 3
70 paddusb m7
, m1
; d+128+1
75 movq m5
, [r2
+516] ; flim
92 %macro STORE_4_WORDS
1
105 cglobal vp3_v_loop_filter
, 3, 4
122 cglobal vp3_h_loop_filter
, 3, 4
133 punpcklbw m6
, [r0
-2]
134 punpcklbw m4
, [r0
+r1
-2]
135 punpcklbw m2
, [r0
+r1
*2-2]
136 punpcklbw m1
, [r0
+r3
-2]
140 TRANSPOSE4x4B
6, 4, 2, 1, 0
142 SBUTTERFLY bw
, 4, 3, 5
149 ; from original comments: The Macro does IDct on 4 1-D Dcts
155 pmulhw m4
, m6
; r4 = c3*i3 - i3
157 pmulhw m6
, m7
; r6 = c3*i5 - i5
159 pmulhw m1
, m2
; r1 = c5*i3 - i3
161 pmulhw m5
, m7
; r5 = c5*i5 - i5
163 paddw m4
, m2
; r4 = c3*i3
164 paddw m6
, m7
; r6 = c3*i5
165 paddw m2
, m1
; r2 = c5*i3
167 paddw m7
, m5
; r7 = c5*i5
168 movq m5
, m0
; r5 = c1
169 pmulhw m0
, m3
; r0 = c1*i1 - i1
170 paddsw m4
, m7
; r4 = C = c3*i3 + c5*i5
171 pmulhw m5
, m1
; r5 = c1*i7 - i7
173 psubsw m6
, m2
; r6 = D = c3*i5 - c5*i3
174 paddw m0
, m3
; r0 = c1*i1
175 pmulhw m3
, m7
; r3 = c7*i1
177 pmulhw m7
, m1
; r7 = c7*i7
178 paddw m5
, m1
; r5 = c1*i7
179 movq m1
, m2
; r1 = i2
180 pmulhw m2
, C
(2) ; r2 = c2*i2 - i2
181 psubsw m3
, m5
; r3 = B = c7*i1 - c1*i7
183 paddsw m0
, m7
; r0 = A = c1*i1 + c7*i7
184 movq m7
, m5
; r7 = i6
185 psubsw m0
, m4
; r0 = A - C
186 pmulhw m5
, C
(2) ; r5 = c2*i6 - i6
187 paddw m2
, m1
; r2 = c2*i2
188 pmulhw m1
, C
(6) ; r1 = c6*i2
189 paddsw m4
, m4
; r4 = C + C
190 paddsw m4
, m0
; r4 = C. = A + C
191 psubsw m3
, m6
; r3 = B - D
192 paddw m5
, m7
; r5 = c2*i6
193 paddsw m6
, m6
; r6 = D + D
194 pmulhw m7
, C
(6) ; r7 = c6*i6
195 paddsw m6
, m3
; r6 = D. = B + D
196 movq I
(1), m4
; save C. at I(1)
197 psubsw m1
, m5
; r1 = H = c6*i2 - c2*i6
199 movq m5
, m3
; r5 = B - D
200 pmulhw m3
, m4
; r3 = (c4 - 1) * (B - D)
201 paddsw m7
, m2
; r3 = (c4 - 1) * (B - D)
202 movq I
(2), m6
; save D. at I(2)
203 movq m2
, m0
; r2 = A - C
205 pmulhw m0
, m4
; r0 = (c4 - 1) * (A - C)
206 paddw m5
, m3
; r5 = B. = c4 * (B - D)
208 psubsw m5
, m1
; r5 = B.. = B. - H
209 paddw m2
, m0
; r0 = A. = c4 * (A - C)
210 psubsw m6
, m3
; r6 = i0 - i4
212 pmulhw m6
, m4
; r6 = (c4 - 1) * (i0 - i4)
213 paddsw m3
, m3
; r3 = i4 + i4
214 paddsw m1
, m1
; r1 = H + H
215 paddsw m3
, m0
; r3 = i0 + i4
216 paddsw m1
, m5
; r1 = H. = B + H
217 pmulhw m4
, m3
; r4 = (c4 - 1) * (i0 + i4)
218 paddsw m6
, m0
; r6 = F = c4 * (i0 - i4)
219 psubsw m6
, m2
; r6 = F. = F - A.
220 paddsw m2
, m2
; r2 = A. + A.
221 movq m0
, I
(1) ; r0 = C.
222 paddsw m2
, m6
; r2 = A.. = F + A.
223 paddw m4
, m3
; r4 = E = c4 * (i0 + i4)
224 psubsw m2
, m1
; r2 = R2 = A.. - H.
227 ; RowIDCT gets ready to transpose
230 movq m3
, I
(2) ; r3 = D.
231 psubsw m4
, m7
; r4 = E. = E - G
232 paddsw m1
, m1
; r1 = H. + H.
233 paddsw m7
, m7
; r7 = G + G
234 paddsw m1
, m2
; r1 = R1 = A.. + H.
235 paddsw m7
, m4
; r1 = R1 = A.. + H.
236 psubsw m4
, m3
; r4 = R4 = E. - D.
238 psubsw m6
, m5
; r6 = R6 = F. - B..
240 paddsw m3
, m4
; r3 = R3 = E. + D.
241 paddsw m5
, m6
; r5 = R5 = F. + B..
242 psubsw m7
, m0
; r7 = R7 = G. - C.
244 movq I
(1), m1
; save R1
245 paddsw m0
, m7
; r0 = R0 = G. + C.
248 ; Column IDCT normalizes and stores final results
251 paddsw m2
, OC_8
; adjust R2 (and R1) for shift
252 paddsw m1
, m1
; r1 = H. + H.
253 paddsw m1
, m2
; r1 = R1 = A.. + H.
254 psraw m2
, 4 ; r2 = NR2
255 psubsw m4
, m7
; r4 = E. = E - G
256 psraw m1
, 4 ; r1 = NR2
257 movq m3
, I
(2) ; r3 = D.
258 paddsw m7
, m7
; r7 = G + G
259 movq I
(2), m2
; store NR2 at I2
260 paddsw m7
, m4
; r7 = G. = E + G
261 movq I
(1), m1
; store NR1 at I1
262 psubsw m4
, m3
; r4 = R4 = E. - D.
263 paddsw m4
, OC_8
; adjust R4 (and R3) for shift
264 paddsw m3
, m3
; r3 = D. + D.
265 paddsw m3
, m4
; r3 = R3 = E. + D.
266 psraw m4
, 4 ; r4 = NR4
267 psubsw m6
, m5
; r6 = R6 = F. - B..
268 psraw m3
, 4 ; r3 = NR3
269 paddsw m6
, OC_8
; adjust R6 (and R5) for shift
270 paddsw m5
, m5
; r5 = B.. + B..
271 paddsw m5
, m6
; r5 = R5 = F. + B..
272 psraw m6
, 4 ; r6 = NR6
273 movq J
(4), m4
; store NR4 at J4
274 psraw m5
, 4 ; r5 = NR5
275 movq I
(3), m3
; store NR3 at I3
276 psubsw m7
, m0
; r7 = R7 = G. - C.
277 paddsw m7
, OC_8
; adjust R7 (and R0) for shift
278 paddsw m0
, m0
; r0 = C. + C.
279 paddsw m0
, m7
; r0 = R0 = G. + C.
280 psraw m7
, 4 ; r7 = NR7
281 movq J
(6), m6
; store NR6 at J6
282 psraw m0
, 4 ; r0 = NR0
283 movq J
(5), m5
; store NR5 at J5
284 movq J
(7), m7
; store NR7 at J7
285 movq I
(0), m0
; store NR0 at I0
288 ; Following macro does two 4x4 transposes in place.
290 ; At entry (we assume):
314 ; I(0) I(1) I(2) I(3) is the transpose of r0 I(1) r2 r3.
315 ; J(4) J(5) J(6) J(7) is the transpose of r4 r5 r6 r7.
317 ; Since r1 is free at entry, we calculate the Js first.
319 movq m1
, m4
; r1 = e3 e2 e1 e0
320 punpcklwd m4
, m5
; r4 = f1 e1 f0 e0
321 movq I
(0), m0
; save a3 a2 a1 a0
322 punpckhwd m1
, m5
; r1 = f3 e3 f2 e2
323 movq m0
, m6
; r0 = g3 g2 g1 g0
324 punpcklwd m6
, m7
; r6 = h1 g1 h0 g0
325 movq m5
, m4
; r5 = f1 e1 f0 e0
326 punpckldq m4
, m6
; r4 = h0 g0 f0 e0 = R4
327 punpckhdq m5
, m6
; r5 = h1 g1 f1 e1 = R5
328 movq m6
, m1
; r6 = f3 e3 f2 e2
330 punpckhwd m0
, m7
; r0 = h3 g3 h2 g2
332 punpckhdq m6
, m0
; r6 = h3 g3 f3 e3 = R7
333 movq m4
, I
(0) ; r4 = a3 a2 a1 a0
334 punpckldq m1
, m0
; r1 = h2 g2 f2 e2 = R6
335 movq m5
, I
(1) ; r5 = b3 b2 b1 b0
336 movq m0
, m4
; r0 = a3 a2 a1 a0
338 punpcklwd m0
, m5
; r0 = b1 a1 b0 a0
340 punpckhwd m4
, m5
; r4 = b3 a3 b2 a2
341 movq m5
, m2
; r5 = c3 c2 c1 c0
342 punpcklwd m2
, m3
; r2 = d1 c1 d0 c0
343 movq m1
, m0
; r1 = b1 a1 b0 a0
344 punpckldq m0
, m2
; r0 = d0 c0 b0 a0 = R0
345 punpckhdq m1
, m2
; r1 = d1 c1 b1 a1 = R1
346 movq m2
, m4
; r2 = b3 a3 b2 a2
348 punpckhwd m5
, m3
; r5 = d3 c3 d2 c2
350 punpckhdq m4
, m5
; r4 = d3 c3 b3 a3 = R3
351 punpckldq m2
, m5
; r2 = d2 c2 b2 a2 = R2
356 %macro VP3_1D_IDCT_SSE2
0
357 movdqa m2
, I
(3) ; xmm2 = i3
358 movdqa m6
, C
(3) ; xmm6 = c3
359 movdqa m4
, m2
; xmm4 = i3
360 movdqa m7
, I
(5) ; xmm7 = i5
361 pmulhw m4
, m6
; xmm4 = c3 * i3 - i3
362 movdqa m1
, C
(5) ; xmm1 = c5
363 pmulhw m6
, m7
; xmm6 = c3 * i5 - i5
364 movdqa m5
, m1
; xmm5 = c5
365 pmulhw m1
, m2
; xmm1 = c5 * i3 - i3
366 movdqa m3
, I
(1) ; xmm3 = i1
367 pmulhw m5
, m7
; xmm5 = c5 * i5 - i5
368 movdqa m0
, C
(1) ; xmm0 = c1
369 paddw m4
, m2
; xmm4 = c3 * i3
370 paddw m6
, m7
; xmm6 = c3 * i5
371 paddw m2
, m1
; xmm2 = c5 * i3
372 movdqa m1
, I
(7) ; xmm1 = i7
373 paddw m7
, m5
; xmm7 = c5 * i5
374 movdqa m5
, m0
; xmm5 = c1
375 pmulhw m0
, m3
; xmm0 = c1 * i1 - i1
376 paddsw m4
, m7
; xmm4 = c3 * i3 + c5 * i5 = C
377 pmulhw m5
, m1
; xmm5 = c1 * i7 - i7
378 movdqa m7
, C
(7) ; xmm7 = c7
379 psubsw m6
, m2
; xmm6 = c3 * i5 - c5 * i3 = D
380 paddw m0
, m3
; xmm0 = c1 * i1
381 pmulhw m3
, m7
; xmm3 = c7 * i1
382 movdqa m2
, I
(2) ; xmm2 = i2
383 pmulhw m7
, m1
; xmm7 = c7 * i7
384 paddw m5
, m1
; xmm5 = c1 * i7
385 movdqa m1
, m2
; xmm1 = i2
386 pmulhw m2
, C
(2) ; xmm2 = i2 * c2 -i2
387 psubsw m3
, m5
; xmm3 = c7 * i1 - c1 * i7 = B
388 movdqa m5
, I
(6) ; xmm5 = i6
389 paddsw m0
, m7
; xmm0 = c1 * i1 + c7 * i7 = A
390 movdqa m7
, m5
; xmm7 = i6
391 psubsw m0
, m4
; xmm0 = A - C
392 pmulhw m5
, C
(2) ; xmm5 = c2 * i6 - i6
393 paddw m2
, m1
; xmm2 = i2 * c2
394 pmulhw m1
, C
(6) ; xmm1 = c6 * i2
395 paddsw m4
, m4
; xmm4 = C + C
396 paddsw m4
, m0
; xmm4 = A + C = C.
397 psubsw m3
, m6
; xmm3 = B - D
398 paddw m5
, m7
; xmm5 = c2 * i6
399 paddsw m6
, m6
; xmm6 = D + D
400 pmulhw m7
, C
(6) ; xmm7 = c6 * i6
401 paddsw m6
, m3
; xmm6 = B + D = D.
402 movdqa I
(1), m4
; Save C. at I(1)
403 psubsw m1
, m5
; xmm1 = c6 * i2 - c2 * i6 = H
404 movdqa m4
, C
(4) ; xmm4 = C4
405 movdqa m5
, m3
; xmm5 = B - D
406 pmulhw m3
, m4
; xmm3 = ( c4 -1 ) * ( B - D )
407 paddsw m7
, m2
; xmm7 = c2 * i2 + c6 * i6 = G
408 movdqa I
(2), m6
; save D. at I(2)
409 movdqa m2
, m0
; xmm2 = A - C
410 movdqa m6
, I
(0) ; xmm6 = i0
411 pmulhw m0
, m4
; xmm0 = ( c4 - 1 ) * ( A - C ) = A.
412 paddw m5
, m3
; xmm5 = c4 * ( B - D ) = B.
413 movdqa m3
, I
(4) ; xmm3 = i4
414 psubsw m5
, m1
; xmm5 = B. - H = B..
415 paddw m2
, m0
; xmm2 = c4 * ( A - C) = A.
416 psubsw m6
, m3
; xmm6 = i0 - i4
417 movdqa m0
, m6
; xmm0 = i0 - i4
418 pmulhw m6
, m4
; xmm6 = (c4 - 1) * (i0 - i4) = F
419 paddsw m3
, m3
; xmm3 = i4 + i4
420 paddsw m1
, m1
; xmm1 = H + H
421 paddsw m3
, m0
; xmm3 = i0 + i4
422 paddsw m1
, m5
; xmm1 = B. + H = H.
423 pmulhw m4
, m3
; xmm4 = ( c4 - 1 ) * ( i0 + i4 )
424 paddw m6
, m0
; xmm6 = c4 * ( i0 - i4 )
425 psubsw m6
, m2
; xmm6 = F - A. = F.
426 paddsw m2
, m2
; xmm2 = A. + A.
427 movdqa m0
, I
(1) ; Load C. from I(1)
428 paddsw m2
, m6
; xmm2 = F + A. = A..
429 paddw m4
, m3
; xmm4 = c4 * ( i0 + i4 ) = 3
430 psubsw m2
, m1
; xmm2 = A.. - H. = R2
431 ADD(m2
) ; Adjust R2 and R1 before shifting
432 paddsw m1
, m1
; xmm1 = H. + H.
433 paddsw m1
, m2
; xmm1 = A.. + H. = R1
434 SHIFT
(m2
) ; xmm2 = op2
435 psubsw m4
, m7
; xmm4 = E - G = E.
436 SHIFT
(m1
) ; xmm1 = op1
437 movdqa m3
, I
(2) ; Load D. from I(2)
438 paddsw m7
, m7
; xmm7 = G + G
439 paddsw m7
, m4
; xmm7 = E + G = G.
440 psubsw m4
, m3
; xmm4 = E. - D. = R4
441 ADD(m4
) ; Adjust R4 and R3 before shifting
442 paddsw m3
, m3
; xmm3 = D. + D.
443 paddsw m3
, m4
; xmm3 = E. + D. = R3
444 SHIFT
(m4
) ; xmm4 = op4
445 psubsw m6
, m5
; xmm6 = F. - B..= R6
446 SHIFT
(m3
) ; xmm3 = op3
447 ADD(m6
) ; Adjust R6 and R5 before shifting
448 paddsw m5
, m5
; xmm5 = B.. + B..
449 paddsw m5
, m6
; xmm5 = F. + B.. = R5
450 SHIFT
(m6
) ; xmm6 = op6
451 SHIFT
(m5
) ; xmm5 = op5
452 psubsw m7
, m0
; xmm7 = G. - C. = R7
453 ADD(m7
) ; Adjust R7 and R0 before shifting
454 paddsw m0
, m0
; xmm0 = C. + C.
455 paddsw m0
, m7
; xmm0 = G. + C.
456 SHIFT
(m7
) ; xmm7 = op7
457 SHIFT
(m0
) ; xmm0 = op0
473 %define I
(x
) [%1+16*x
]
474 %define O
(x
) [%1+16*x
]
475 %define C
(x
) [vp3_idct_data
+16*(x
-1)]
480 TRANSPOSE8x8W
0, 1, 2, 3, 4, 5, 6, 7, 8
482 TRANSPOSE8x8W
0, 1, 2, 3, 4, 5, 6, 7, [%1], [%1+16]
484 PUT_BLOCK
0, 1, 2, 3, 4, 5, 6, 7
486 %define SHIFT
(x
) psraw x
, 4
487 %define
ADD(x
) paddsw x
, [pw_8
]
489 PUT_BLOCK
0, 1, 2, 3, 4, 5, 6, 7
491 ; eax = quantized input
492 ; ebx = dequantizer matrix
493 ; ecx = IDCT constants
494 ; M(I) = ecx + MaskOffset(0) + I * 8
495 ; C(I) = ecx + CosineOffset(32) + (I-1) * 8
499 %define C
(x
) [vp3_idct_data
+16*(x
-1)]
501 ; at this point, function has completed dequantization + dezigzag +
502 ; partial transposition; now do the idct itself
503 %define I
(x
) [%1+16* x
]
504 %define J
(x
) [%1+16*(x
-4)+8]
508 %define I
(x
) [%1+16* x
+64]
509 %define J
(x
) [%1+16*(x
-4)+72]
513 %define I
(x
) [%1+16*x
]
514 %define J
(x
) [%1+16*x
]
517 %define I
(x
) [%1+16*x
+8]
518 %define J
(x
) [%1+16*x
+8]
520 %endif
; mmsize == 16/8
523 %macro vp3_idct_funcs
0
524 cglobal vp3_idct_put
, 3, 4, 9
532 mova m0
, [r2
+mmsize
*0+%%i
]
533 mova m1
, [r2
+mmsize
*2+%%i
]
534 mova m2
, [r2
+mmsize
*4+%%i
]
535 mova m3
, [r2
+mmsize
*6+%%i
]
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
]
569 mova
[r2
+%%offset], m0
570 %assign
%%offset %%offset+mmsize
574 cglobal vp3_idct_add
, 3, 4, 9
612 mova
[r2
+%%offset], m4
613 %assign
%%offset %%offset+mmsize
649 cglobal vp3_idct_dc_add
, 3, 4