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
37 pb_1F: times 8 db 0x1f
38 pb_81: times 8 db 0x81
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
53 pand m6, [pb_7] ; p0&7
55 pand m7, [pb_1F] ; p0>>3
58 pand m2, [pb_1] ; (p2^p1)&1
61 paddb m2, m5 ; 3*(p2^p1)&1
62 paddb m2, m6 ; extra bits lost in shifts
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
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
76 movq m5, [r2+516] ; flim
93 %macro STORE_4_WORDS 1
106 cglobal vp3_v_loop_filter, 3, 4
120 cglobal vp3_h_loop_filter, 3, 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]
135 TRANSPOSE4x4B 6, 4, 2, 1, 0
137 SBUTTERFLY bw, 4, 3, 5
144 ; from original comments: The Macro does IDct on 4 1-D Dcts
150 pmulhw m4, m6 ; r4 = c3*i3 - i3
152 pmulhw m6, m7 ; r6 = c3*i5 - i5
154 pmulhw m1, m2 ; r1 = c5*i3 - i3
156 pmulhw m5, m7 ; r5 = c5*i5 - i5
158 paddw m4, m2 ; r4 = c3*i3
159 paddw m6, m7 ; r6 = c3*i5
160 paddw m2, m1 ; r2 = c5*i3
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
168 psubsw m6, m2 ; r6 = D = c3*i5 - c5*i3
169 paddw m0, m3 ; r0 = c1*i1
170 pmulhw m3, m7 ; r3 = c7*i1
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
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
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
200 pmulhw m0, m4 ; r0 = (c4 - 1) * (A - C)
201 paddw m5, m3 ; r5 = B. = c4 * (B - D)
203 psubsw m5, m1 ; r5 = B.. = B. - H
204 paddw m2, m0 ; r0 = A. = c4 * (A - C)
205 psubsw m6, m3 ; r6 = i0 - i4
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.
222 ; RowIDCT gets ready to transpose
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.
233 psubsw m6, m5 ; r6 = R6 = F. - B..
235 paddsw m3, m4 ; r3 = R3 = E. + D.
236 paddsw m5, m6 ; r5 = R5 = F. + B..
237 psubsw m7, m0 ; r7 = R7 = G. - C.
239 movq I(1), m1 ; save R1
240 paddsw m0, m7 ; r0 = R0 = G. + C.
243 ; Column IDCT normalizes and stores final results
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
283 ; Following macro does two 4x4 transposes in place.
285 ; At entry (we assume):
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.
312 ; Since r1 is free at entry, we calculate the Js first.
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
325 punpckhwd m0, m7 ; r0 = h3 g3 h2 g2
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
333 punpcklwd m0, m5 ; r0 = b1 a1 b0 a0
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
343 punpckhwd m5, m3 ; r5 = d3 c3 d2 c2
345 punpckhdq m4, m5 ; r4 = d3 c3 b3 a3 = R3
346 punpckldq m2, m5 ; r2 = d2 c2 b2 a2 = R2
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
468 %define I(x) [%1+16*x]
469 %define O(x) [%1+16*x]
470 %define C(x) [vp3_idct_data+16*(x-1)]
475 TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, 8
477 TRANSPOSE8x8W 0, 1, 2, 3, 4, 5, 6, 7, [%1], [%1+16]
479 PUT_BLOCK 0, 1, 2, 3, 4, 5, 6, 7
481 %define SHIFT(x) psraw x, 4
482 %define ADD(x) paddsw x, [pw_8]
484 PUT_BLOCK 0, 1, 2, 3, 4, 5, 6, 7
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
494 %define C(x) [vp3_idct_data+16*(x-1)]
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]
503 %define I(x) [%1+16*x+8]
504 %define J(x) [%1+16*x+8]
508 %define I(x) [%1+16* x]
509 %define J(x) [%1+16*(x-4)+8]
512 %define I(x) [%1+16* x +64]
513 %define J(x) [%1+16*(x-4)+72]
515 %endif ; mmsize == 16/8
518 %macro vp3_idct_funcs 0
519 cglobal vp3_idct_put, 3, 4, 9
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]
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]
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]
570 mova [r2+%%offset], m0
571 %assign %%offset %%offset+mmsize
575 cglobal vp3_idct_add, 3, 4, 9
591 paddsw m0, [r2+ 0+%%i]
592 paddsw m1, [r2+16+%%i]
593 paddsw m2, [r2+32+%%i]
594 paddsw m3, [r2+48+%%i]
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]
633 paddsw m3, [r2+48+%%i]
634 paddsw m5, [r2+112+%%i]
650 %assign %%i %%i+mmsize
683 cglobal vp3_idct_dc_add, 3, 4