]> git.sesse.net Git - x264/blob - common/x86/deblock-a.asm
Convert x264 to use NV12 pixel format internally
[x264] / common / x86 / deblock-a.asm
1 ;*****************************************************************************
2 ;* deblock-a.asm: h264 encoder library
3 ;*****************************************************************************
4 ;* Copyright (C) 2005-2008 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Fiona Glaser <fiona@x264.com>
8 ;*
9 ;* This program is free software; you can redistribute it and/or modify
10 ;* it under the terms of the GNU General Public License as published by
11 ;* the Free Software Foundation; either version 2 of the License, or
12 ;* (at your option) any later version.
13 ;*
14 ;* This program is distributed in the hope that it will be useful,
15 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;* GNU General Public License for more details.
18 ;*
19 ;* You should have received a copy of the GNU General Public License
20 ;* along with this program; if not, write to the Free Software
21 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22 ;*****************************************************************************
23
24 %include "x86inc.asm"
25 %include "x86util.asm"
26
27 SECTION_RODATA
28
29 transpose_shuf: db 0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15
30
31 SECTION .text
32
33 cextern pb_0
34 cextern pb_1
35 cextern pb_3
36 cextern pb_a1
37
38 ; expands to [base],...,[base+7*stride]
39 %define PASS8ROWS(base, base3, stride, stride3) \
40     [base], [base+stride], [base+stride*2], [base3], \
41     [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
42
43 %define PASS8ROWS(base, base3, stride, stride3, offset) \
44     PASS8ROWS(base+offset, base3+offset, stride, stride3)
45
46 ; in: 8 rows of 4 bytes in %4..%11
47 ; out: 4 rows of 8 bytes in m0..m3
48 %macro TRANSPOSE4x8_LOAD 11
49     movh       m0, %4
50     movh       m2, %5
51     movh       m1, %6
52     movh       m3, %7
53     punpckl%1  m0, m2
54     punpckl%1  m1, m3
55     mova       m2, m0
56     punpckl%2  m0, m1
57     punpckh%2  m2, m1
58
59     movh       m4, %8
60     movh       m6, %9
61     movh       m5, %10
62     movh       m7, %11
63     punpckl%1  m4, m6
64     punpckl%1  m5, m7
65     mova       m6, m4
66     punpckl%2  m4, m5
67     punpckh%2  m6, m5
68
69     mova       m1, m0
70     mova       m3, m2
71     punpckl%3  m0, m4
72     punpckh%3  m1, m4
73     punpckl%3  m2, m6
74     punpckh%3  m3, m6
75 %endmacro
76
77 ; in: 4 rows of 8 bytes in m0..m3
78 ; out: 8 rows of 4 bytes in %1..%8
79 %macro TRANSPOSE8x4B_STORE 8
80     mova       m4, m0
81     mova       m5, m1
82     mova       m6, m2
83     punpckhdq  m4, m4
84     punpckhdq  m5, m5
85     punpckhdq  m6, m6
86
87     punpcklbw  m0, m1
88     punpcklbw  m2, m3
89     mova       m1, m0
90     punpcklwd  m0, m2
91     punpckhwd  m1, m2
92     movh       %1, m0
93     punpckhdq  m0, m0
94     movh       %2, m0
95     movh       %3, m1
96     punpckhdq  m1, m1
97     movh       %4, m1
98
99     punpckhdq  m3, m3
100     punpcklbw  m4, m5
101     punpcklbw  m6, m3
102     mova       m5, m4
103     punpcklwd  m4, m6
104     punpckhwd  m5, m6
105     movh       %5, m4
106     punpckhdq  m4, m4
107     movh       %6, m4
108     movh       %7, m5
109     punpckhdq  m5, m5
110     movh       %8, m5
111 %endmacro
112
113 %macro TRANSPOSE4x8B_LOAD 8
114     TRANSPOSE4x8_LOAD bw, wd, dq, %1, %2, %3, %4, %5, %6, %7, %8
115 %endmacro
116
117 %macro TRANSPOSE4x8W_LOAD 8
118 %if mmsize==16
119     TRANSPOSE4x8_LOAD wd, dq, qdq, %1, %2, %3, %4, %5, %6, %7, %8
120 %else
121     SWAP  1, 4, 2, 3
122     mova  m0, [t5]
123     mova  m1, [t5+r1]
124     mova  m2, [t5+r1*2]
125     mova  m3, [t5+t6]
126     TRANSPOSE4x4W 0, 1, 2, 3, 4
127 %endif
128 %endmacro
129
130 %macro TRANSPOSE8x2W_STORE 8
131     mova       m0, m1
132     punpcklwd  m1, m2
133     punpckhwd  m0, m2
134 %if mmsize==8
135     movd       %1, m1
136     movd       %3, m0
137     psrlq      m1, 32
138     psrlq      m0, 32
139     movd       %2, m1
140     movd       %4, m0
141 %else
142     movd       %1, m1
143     movd       %5, m0
144     psrldq     m1, 4
145     psrldq     m0, 4
146     movd       %2, m1
147     movd       %6, m0
148     psrldq     m1, 4
149     psrldq     m0, 4
150     movd       %3, m1
151     movd       %7, m0
152     psrldq     m1, 4
153     psrldq     m0, 4
154     movd       %4, m1
155     movd       %8, m0
156 %endif
157 %endmacro
158
159 %macro SBUTTERFLY3 4
160     movq       %4, %2
161     punpckl%1  %2, %3
162     punpckh%1  %4, %3
163 %endmacro
164
165 ; in: 8 rows of 8 (only the middle 6 pels are used) in %1..%8
166 ; out: 6 rows of 8 in [%9+0*16] .. [%9+5*16]
167 %macro TRANSPOSE6x8_MEM 9
168     RESET_MM_PERMUTATION
169     movq  m0, %1
170     movq  m1, %2
171     movq  m2, %3
172     movq  m3, %4
173     movq  m4, %5
174     movq  m5, %6
175     movq  m6, %7
176     SBUTTERFLY bw, 0, 1, 7
177     SBUTTERFLY bw, 2, 3, 7
178     SBUTTERFLY bw, 4, 5, 7
179     movq  [%9+0x10], m3
180     SBUTTERFLY3 bw, m6, %8, m7
181     SBUTTERFLY wd, 0, 2, 3
182     SBUTTERFLY wd, 4, 6, 3
183     punpckhdq m0, m4
184     movq  [%9+0x00], m0
185     SBUTTERFLY3 wd, m1, [%9+0x10], m3
186     SBUTTERFLY wd, 5, 7, 0
187     SBUTTERFLY dq, 1, 5, 0
188     SBUTTERFLY dq, 2, 6, 0
189     punpckldq m3, m7
190     movq  [%9+0x10], m2
191     movq  [%9+0x20], m6
192     movq  [%9+0x30], m1
193     movq  [%9+0x40], m5
194     movq  [%9+0x50], m3
195     RESET_MM_PERMUTATION
196 %endmacro
197
198 ; in: 8 rows of 8 in %1..%8
199 ; out: 8 rows of 8 in %9..%16
200 %macro TRANSPOSE8x8_MEM 16
201     RESET_MM_PERMUTATION
202     movq  m0, %1
203     movq  m1, %2
204     movq  m2, %3
205     movq  m3, %4
206     movq  m4, %5
207     movq  m5, %6
208     movq  m6, %7
209     SBUTTERFLY bw, 0, 1, 7
210     SBUTTERFLY bw, 2, 3, 7
211     SBUTTERFLY bw, 4, 5, 7
212     SBUTTERFLY3 bw, m6, %8, m7
213     movq  %9,  m5
214     SBUTTERFLY wd, 0, 2, 5
215     SBUTTERFLY wd, 4, 6, 5
216     SBUTTERFLY wd, 1, 3, 5
217     movq  %11, m6
218     movq  m6,  %9
219     SBUTTERFLY wd, 6, 7, 5
220     SBUTTERFLY dq, 0, 4, 5
221     SBUTTERFLY dq, 1, 6, 5
222     movq  %9,  m0
223     movq  %10, m4
224     movq  %13, m1
225     movq  %14, m6
226     SBUTTERFLY3 dq, m2, %11, m0
227     SBUTTERFLY dq, 3, 7, 4
228     movq  %11, m2
229     movq  %12, m0
230     movq  %15, m3
231     movq  %16, m7
232     RESET_MM_PERMUTATION
233 %endmacro
234
235 ; out: %4 = |%1-%2|>%3
236 ; clobbers: %5
237 %macro DIFF_GT 5
238     mova    %5, %2
239     mova    %4, %1
240     psubusb %5, %1
241     psubusb %4, %2
242     por     %4, %5
243     psubusb %4, %3
244 %endmacro
245
246 ; out: %4 = |%1-%2|>%3
247 ; clobbers: %5
248 %macro DIFF_GT2 5
249     mova    %5, %2
250     mova    %4, %1
251     psubusb %5, %1
252     psubusb %4, %2
253     psubusb %5, %3
254     psubusb %4, %3
255     pcmpeqb %4, %5
256 %endmacro
257
258 %macro SPLATW 1
259 %ifidn m0, xmm0
260     pshuflw  %1, %1, 0
261     punpcklqdq %1, %1
262 %else
263     pshufw   %1, %1, 0
264 %endif
265 %endmacro
266
267 ; in: m0=p1 m1=p0 m2=q0 m3=q1 %1=alpha-1 %2=beta-1
268 ; out: m5=beta-1, m7=mask, %3=alpha-1
269 ; clobbers: m4,m6
270 %macro LOAD_MASK 2-3
271     movd     m4, %1
272     movd     m5, %2
273     SPLATW   m4
274     SPLATW   m5
275     packuswb m4, m4  ; 16x alpha-1
276     packuswb m5, m5  ; 16x beta-1
277 %if %0>2
278     mova     %3, m4
279 %endif
280     DIFF_GT  m1, m2, m4, m7, m6 ; |p0-q0| > alpha-1
281     DIFF_GT  m0, m1, m5, m4, m6 ; |p1-p0| > beta-1
282     por      m7, m4
283     DIFF_GT  m3, m2, m5, m4, m6 ; |q1-q0| > beta-1
284     por      m7, m4
285     pxor     m6, m6
286     pcmpeqb  m7, m6
287 %endmacro
288
289 ; in: m0=p1 m1=p0 m2=q0 m3=q1 m7=(tc&mask)
290 ; out: m1=p0' m2=q0'
291 ; clobbers: m0,3-6
292 %macro DEBLOCK_P0_Q0 0
293     mova    m5, m1
294     pxor    m5, m2       ; p0^q0
295     pand    m5, [pb_1]   ; (p0^q0)&1
296     pcmpeqb m4, m4
297     pxor    m3, m4
298     pavgb   m3, m0       ; (p1 - q1 + 256)>>1
299     pavgb   m3, [pb_3]   ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2
300     pxor    m4, m1
301     pavgb   m4, m2       ; (q0 - p0 + 256)>>1
302     pavgb   m3, m5
303     paddusb m3, m4       ; d+128+33
304     mova    m6, [pb_a1]
305     psubusb m6, m3
306     psubusb m3, [pb_a1]
307     pminub  m6, m7
308     pminub  m3, m7
309     psubusb m1, m6
310     psubusb m2, m3
311     paddusb m1, m3
312     paddusb m2, m6
313 %endmacro
314
315 ; in: m1=p0 m2=q0
316 ;     %1=p1 %2=q2 %3=[q2] %4=[q1] %5=tc0 %6=tmp
317 ; out: [q1] = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 )
318 ; clobbers: q2, tmp, tc0
319 %macro LUMA_Q1 6
320     mova    %6, m1
321     pavgb   %6, m2
322     pavgb   %2, %6       ; avg(p2,avg(p0,q0))
323     pxor    %6, %3
324     pand    %6, [pb_1]   ; (p2^avg(p0,q0))&1
325     psubusb %2, %6       ; (p2+((p0+q0+1)>>1))>>1
326     mova    %6, %1
327     psubusb %6, %5
328     paddusb %5, %1
329     pmaxub  %2, %6
330     pminub  %2, %5
331     mova    %4, %2
332 %endmacro
333
334 %ifdef ARCH_X86_64
335 ;-----------------------------------------------------------------------------
336 ; void deblock_v_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
337 ;-----------------------------------------------------------------------------
338 INIT_XMM
339 cglobal deblock_v_luma_sse2, 5,5,10
340     movd    m8, [r4] ; tc0
341     lea     r4, [r1*3]
342     dec     r2d        ; alpha-1
343     neg     r4
344     dec     r3d        ; beta-1
345     add     r4, r0     ; pix-3*stride
346
347     mova    m0, [r4+r1]   ; p1
348     mova    m1, [r4+2*r1] ; p0
349     mova    m2, [r0]      ; q0
350     mova    m3, [r0+r1]   ; q1
351     LOAD_MASK r2d, r3d
352
353     punpcklbw m8, m8
354     punpcklbw m8, m8 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
355     pcmpeqb m9, m9
356     pcmpeqb m9, m8
357     pandn   m9, m7
358     pand    m8, m9
359
360     movdqa  m3, [r4] ; p2
361     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
362     pand    m6, m9
363     mova    m7, m8
364     psubb   m7, m6
365     pand    m6, m8
366     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
367
368     movdqa  m4, [r0+2*r1] ; q2
369     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
370     pand    m6, m9
371     pand    m8, m6
372     psubb   m7, m6
373     mova    m3, [r0+r1]
374     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m8, m6
375
376     DEBLOCK_P0_Q0
377     mova    [r4+2*r1], m1
378     mova    [r0], m2
379     RET
380
381 ;-----------------------------------------------------------------------------
382 ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
383 ;-----------------------------------------------------------------------------
384 INIT_MMX
385 cglobal deblock_h_luma_sse2, 5,7
386     movsxd r10, r1d
387     lea    r11, [r10+r10*2]
388     lea    r6,  [r0-4]
389     lea    r5,  [r0-4+r11]
390 %ifdef WIN64
391     sub    rsp, 0x98
392     %define pix_tmp rsp+0x30
393 %else
394     sub    rsp, 0x68
395     %define pix_tmp rsp
396 %endif
397
398     ; transpose 6x16 -> tmp space
399     TRANSPOSE6x8_MEM  PASS8ROWS(r6, r5, r10, r11), pix_tmp
400     lea    r6, [r6+r10*8]
401     lea    r5, [r5+r10*8]
402     TRANSPOSE6x8_MEM  PASS8ROWS(r6, r5, r10, r11), pix_tmp+8
403
404     ; vertical filter
405     ; alpha, beta, tc0 are still in r2d, r3d, r4
406     ; don't backup r6, r5, r10, r11 because deblock_v_luma_sse2 doesn't use them
407     lea    r0, [pix_tmp+0x30]
408     mov    r1d, 0x10
409 %ifdef WIN64
410     mov    [rsp+0x20], r4
411 %endif
412     call   deblock_v_luma_sse2
413
414     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
415     add    r6, 2
416     add    r5, 2
417     movq   m0, [pix_tmp+0x18]
418     movq   m1, [pix_tmp+0x28]
419     movq   m2, [pix_tmp+0x38]
420     movq   m3, [pix_tmp+0x48]
421     TRANSPOSE8x4B_STORE  PASS8ROWS(r6, r5, r10, r11)
422
423     shl    r10, 3
424     sub    r6,  r10
425     sub    r5,  r10
426     shr    r10, 3
427     movq   m0, [pix_tmp+0x10]
428     movq   m1, [pix_tmp+0x20]
429     movq   m2, [pix_tmp+0x30]
430     movq   m3, [pix_tmp+0x40]
431     TRANSPOSE8x4B_STORE  PASS8ROWS(r6, r5, r10, r11)
432
433 %ifdef WIN64
434     add    rsp, 0x98
435 %else
436     add    rsp, 0x68
437 %endif
438     RET
439
440 %else
441
442 %macro DEBLOCK_LUMA 3
443 ;-----------------------------------------------------------------------------
444 ; void deblock_v8_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
445 ;-----------------------------------------------------------------------------
446 cglobal deblock_%2_luma_%1, 5,5
447     lea     r4, [r1*3]
448     dec     r2     ; alpha-1
449     neg     r4
450     dec     r3     ; beta-1
451     add     r4, r0 ; pix-3*stride
452     %assign pad 2*%3+12-(stack_offset&15)
453     SUB     esp, pad
454
455     mova    m0, [r4+r1]   ; p1
456     mova    m1, [r4+2*r1] ; p0
457     mova    m2, [r0]      ; q0
458     mova    m3, [r0+r1]   ; q1
459     LOAD_MASK r2, r3
460
461     mov     r3, r4mp
462     movd    m4, [r3] ; tc0
463     punpcklbw m4, m4
464     punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
465     mova   [esp+%3], m4 ; tc
466     pcmpeqb m3, m3
467     pcmpgtb m4, m3
468     pand    m4, m7
469     mova   [esp], m4 ; mask
470
471     mova    m3, [r4] ; p2
472     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
473     pand    m6, m4
474     pand    m4, [esp+%3] ; tc
475     mova    m7, m4
476     psubb   m7, m6
477     pand    m6, m4
478     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
479
480     mova    m4, [r0+2*r1] ; q2
481     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
482     mova    m5, [esp] ; mask
483     pand    m6, m5
484     mova    m5, [esp+%3] ; tc
485     pand    m5, m6
486     psubb   m7, m6
487     mova    m3, [r0+r1]
488     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
489
490     DEBLOCK_P0_Q0
491     mova    [r4+2*r1], m1
492     mova    [r0], m2
493     ADD     esp, pad
494     RET
495
496 ;-----------------------------------------------------------------------------
497 ; void deblock_h_luma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
498 ;-----------------------------------------------------------------------------
499 INIT_MMX
500 cglobal deblock_h_luma_%1, 0,5
501     mov    r0, r0mp
502     mov    r3, r1m
503     lea    r4, [r3*3]
504     sub    r0, 4
505     lea    r1, [r0+r4]
506     %assign pad 0x78-(stack_offset&15)
507     SUB    esp, pad
508 %define pix_tmp esp+12
509
510     ; transpose 6x16 -> tmp space
511     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp
512     lea    r0, [r0+r3*8]
513     lea    r1, [r1+r3*8]
514     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
515
516     ; vertical filter
517     lea    r0, [pix_tmp+0x30]
518     PUSH   dword r4m
519     PUSH   dword r3m
520     PUSH   dword r2m
521     PUSH   dword 16
522     PUSH   dword r0
523     call   deblock_%2_luma_%1
524 %ifidn %2, v8
525     add    dword [esp   ], 8 ; pix_tmp+0x38
526     add    dword [esp+16], 2 ; tc0+2
527     call   deblock_%2_luma_%1
528 %endif
529     ADD    esp, 20
530
531     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
532     mov    r0, r0mp
533     sub    r0, 2
534     lea    r1, [r0+r4]
535
536     movq   m0, [pix_tmp+0x10]
537     movq   m1, [pix_tmp+0x20]
538     movq   m2, [pix_tmp+0x30]
539     movq   m3, [pix_tmp+0x40]
540     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
541
542     lea    r0, [r0+r3*8]
543     lea    r1, [r1+r3*8]
544     movq   m0, [pix_tmp+0x18]
545     movq   m1, [pix_tmp+0x28]
546     movq   m2, [pix_tmp+0x38]
547     movq   m3, [pix_tmp+0x48]
548     TRANSPOSE8x4B_STORE  PASS8ROWS(r0, r1, r3, r4)
549
550     ADD    esp, pad
551     RET
552 %endmacro ; DEBLOCK_LUMA
553
554 INIT_MMX
555 DEBLOCK_LUMA mmxext, v8, 8
556 INIT_XMM
557 DEBLOCK_LUMA sse2, v, 16
558
559 %endif ; ARCH
560
561
562
563 %macro LUMA_INTRA_P012 4 ; p0..p3 in memory
564     mova  t0, p2
565     mova  t1, p0
566     pavgb t0, p1
567     pavgb t1, q0
568     pavgb t0, t1 ; ((p2+p1+1)/2 + (p0+q0+1)/2 + 1)/2
569     mova  t5, t1
570     mova  t2, p2
571     mova  t3, p0
572     paddb t2, p1
573     paddb t3, q0
574     paddb t2, t3
575     mova  t3, t2
576     mova  t4, t2
577     psrlw t2, 1
578     pavgb t2, mpb_0
579     pxor  t2, t0
580     pand  t2, mpb_1
581     psubb t0, t2 ; p1' = (p2+p1+p0+q0+2)/4;
582
583     mova  t1, p2
584     mova  t2, p2
585     pavgb t1, q1
586     psubb t2, q1
587     paddb t3, t3
588     psubb t3, t2 ; p2+2*p1+2*p0+2*q0+q1
589     pand  t2, mpb_1
590     psubb t1, t2
591     pavgb t1, p1
592     pavgb t1, t5 ; (((p2+q1)/2 + p1+1)/2 + (p0+q0+1)/2 + 1)/2
593     psrlw t3, 2
594     pavgb t3, mpb_0
595     pxor  t3, t1
596     pand  t3, mpb_1
597     psubb t1, t3 ; p0'a = (p2+2*p1+2*p0+2*q0+q1+4)/8
598
599     mova  t3, p0
600     mova  t2, p0
601     pxor  t3, q1
602     pavgb t2, q1
603     pand  t3, mpb_1
604     psubb t2, t3
605     pavgb t2, p1 ; p0'b = (2*p1+p0+q0+2)/4
606
607     pxor  t1, t2
608     pxor  t2, p0
609     pand  t1, mask1p
610     pand  t2, mask0
611     pxor  t1, t2
612     pxor  t1, p0
613     mova  %1, t1 ; store p0
614
615     mova  t1, %4 ; p3
616     mova  t2, t1
617     pavgb t1, p2
618     paddb t2, p2
619     pavgb t1, t0 ; (p3+p2+1)/2 + (p2+p1+p0+q0+2)/4
620     paddb t2, t2
621     paddb t2, t4 ; 2*p3+3*p2+p1+p0+q0
622     psrlw t2, 2
623     pavgb t2, mpb_0
624     pxor  t2, t1
625     pand  t2, mpb_1
626     psubb t1, t2 ; p2' = (2*p3+3*p2+p1+p0+q0+4)/8
627
628     pxor  t0, p1
629     pxor  t1, p2
630     pand  t0, mask1p
631     pand  t1, mask1p
632     pxor  t0, p1
633     pxor  t1, p2
634     mova  %2, t0 ; store p1
635     mova  %3, t1 ; store p2
636 %endmacro
637
638 %macro LUMA_INTRA_SWAP_PQ 0
639     %define q1 m0
640     %define q0 m1
641     %define p0 m2
642     %define p1 m3
643     %define p2 q2
644     %define mask1p mask1q
645 %endmacro
646
647 %macro DEBLOCK_LUMA_INTRA 2
648     %define p1 m0
649     %define p0 m1
650     %define q0 m2
651     %define q1 m3
652     %define t0 m4
653     %define t1 m5
654     %define t2 m6
655     %define t3 m7
656 %ifdef ARCH_X86_64
657     %define p2 m8
658     %define q2 m9
659     %define t4 m10
660     %define t5 m11
661     %define mask0 m12
662     %define mask1p m13
663     %define mask1q [rsp-24]
664     %define mpb_0 m14
665     %define mpb_1 m15
666 %else
667     %define spill(x) [esp+16*x+((stack_offset+4)&15)]
668     %define p2 [r4+r1]
669     %define q2 [r0+2*r1]
670     %define t4 spill(0)
671     %define t5 spill(1)
672     %define mask0 spill(2)
673     %define mask1p spill(3)
674     %define mask1q spill(4)
675     %define mpb_0 [pb_0]
676     %define mpb_1 [pb_1]
677 %endif
678
679 ;-----------------------------------------------------------------------------
680 ; void deblock_v_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
681 ;-----------------------------------------------------------------------------
682 cglobal deblock_%2_luma_intra_%1, 4,6,16
683 %ifndef ARCH_X86_64
684     sub     esp, 0x60
685 %endif
686     lea     r4, [r1*4]
687     lea     r5, [r1*3] ; 3*stride
688     dec     r2d        ; alpha-1
689     jl .end
690     neg     r4
691     dec     r3d        ; beta-1
692     jl .end
693     add     r4, r0     ; pix-4*stride
694     mova    p1, [r4+2*r1]
695     mova    p0, [r4+r5]
696     mova    q0, [r0]
697     mova    q1, [r0+r1]
698 %ifdef ARCH_X86_64
699     pxor    mpb_0, mpb_0
700     mova    mpb_1, [pb_1]
701     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
702     SWAP    7, 12 ; m12=mask0
703     pavgb   t5, mpb_0
704     pavgb   t5, mpb_1 ; alpha/4+1
705     movdqa  p2, [r4+r1]
706     movdqa  q2, [r0+2*r1]
707     DIFF_GT2 p0, q0, t5, t0, t3 ; t0 = |p0-q0| > alpha/4+1
708     DIFF_GT2 p0, p2, m5, t2, t5 ; mask1 = |p2-p0| > beta-1
709     DIFF_GT2 q0, q2, m5, t4, t5 ; t4 = |q2-q0| > beta-1
710     pand    t0, mask0
711     pand    t4, t0
712     pand    t2, t0
713     mova    mask1q, t4
714     mova    mask1p, t2
715 %else
716     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
717     mova    m4, t5
718     mova    mask0, m7
719     pavgb   m4, [pb_0]
720     pavgb   m4, [pb_1] ; alpha/4+1
721     DIFF_GT2 p0, q0, m4, m6, m7 ; m6 = |p0-q0| > alpha/4+1
722     pand    m6, mask0
723     DIFF_GT2 p0, p2, m5, m4, m7 ; m4 = |p2-p0| > beta-1
724     pand    m4, m6
725     mova    mask1p, m4
726     DIFF_GT2 q0, q2, m5, m4, m7 ; m4 = |q2-q0| > beta-1
727     pand    m4, m6
728     mova    mask1q, m4
729 %endif
730     LUMA_INTRA_P012 [r4+r5], [r4+2*r1], [r4+r1], [r4]
731     LUMA_INTRA_SWAP_PQ
732     LUMA_INTRA_P012 [r0], [r0+r1], [r0+2*r1], [r0+r5]
733 .end:
734 %ifndef ARCH_X86_64
735     add     esp, 0x60
736 %endif
737     RET
738
739 INIT_MMX
740 %ifdef ARCH_X86_64
741 ;-----------------------------------------------------------------------------
742 ; void deblock_h_luma_intra( uint8_t *pix, int stride, int alpha, int beta )
743 ;-----------------------------------------------------------------------------
744 cglobal deblock_h_luma_intra_%1, 4,7
745     movsxd r10, r1d
746     lea    r11, [r10*3]
747     lea    r6,  [r0-4]
748     lea    r5,  [r0-4+r11]
749     sub    rsp, 0x88
750     %define pix_tmp rsp
751
752     ; transpose 8x16 -> tmp space
753     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
754     lea    r6, [r6+r10*8]
755     lea    r5, [r5+r10*8]
756     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
757
758     lea    r0,  [pix_tmp+0x40]
759     mov    r1,  0x10
760     call   deblock_v_luma_intra_%1
761
762     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
763     lea    r5, [r6+r11]
764     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
765     shl    r10, 3
766     sub    r6,  r10
767     sub    r5,  r10
768     shr    r10, 3
769     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
770     add    rsp, 0x88
771     RET
772 %else
773 cglobal deblock_h_luma_intra_%1, 2,4
774     lea    r3,  [r1*3]
775     sub    r0,  4
776     lea    r2,  [r0+r3]
777 %assign pad 0x8c-(stack_offset&15)
778     SUB    rsp, pad
779     %define pix_tmp rsp
780
781     ; transpose 8x16 -> tmp space
782     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
783     lea    r0,  [r0+r1*8]
784     lea    r2,  [r2+r1*8]
785     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
786
787     lea    r0,  [pix_tmp+0x40]
788     PUSH   dword r3m
789     PUSH   dword r2m
790     PUSH   dword 16
791     PUSH   r0
792     call   deblock_%2_luma_intra_%1
793 %ifidn %2, v8
794     add    dword [rsp], 8 ; pix_tmp+8
795     call   deblock_%2_luma_intra_%1
796 %endif
797     ADD    esp, 16
798
799     mov    r1,  r1m
800     mov    r0,  r0mp
801     lea    r3,  [r1*3]
802     sub    r0,  4
803     lea    r2,  [r0+r3]
804     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
805     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
806     lea    r0,  [r0+r1*8]
807     lea    r2,  [r2+r1*8]
808     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
809     ADD    rsp, pad
810     RET
811 %endif ; ARCH_X86_64
812 %endmacro ; DEBLOCK_LUMA_INTRA
813
814 INIT_XMM
815 DEBLOCK_LUMA_INTRA sse2, v
816 %ifndef ARCH_X86_64
817 INIT_MMX
818 DEBLOCK_LUMA_INTRA mmxext, v8
819 %endif
820
821
822
823 %macro CHROMA_V_START 0
824     dec    r2d      ; alpha-1
825     dec    r3d      ; beta-1
826     mov    t5, r0
827     sub    t5, r1
828     sub    t5, r1
829 %if mmsize==8
830     mov   dword r0m, 2
831 .skip_prologue:
832 %endif
833 %endmacro
834
835 %macro CHROMA_H_START 0
836     dec    r2d
837     dec    r3d
838     sub    r0, 4
839     lea    t6, [r1*3]
840     mov    t5, r0
841     add    r0, t6
842 %if mmsize==8
843     mov   dword r0m, 2
844 .skip_prologue:
845 %endif
846 %endmacro
847
848 %macro CHROMA_V_LOOP 1
849 %if mmsize==8
850     add   r0, 8
851     add   t5, 8
852 %if %1
853     add   r4, 2
854 %endif
855     dec   dword r0m
856     jg .skip_prologue
857 %endif
858 %endmacro
859
860 %macro CHROMA_H_LOOP 1
861 %if mmsize==8
862     lea   r0, [r0+r1*4]
863     lea   t5, [t5+r1*4]
864 %if %1
865     add   r4, 2
866 %endif
867     dec   dword r0m
868     jg .skip_prologue
869 %endif
870 %endmacro
871
872 %define t5 r5
873 %define t6 r6
874
875 %macro DEBLOCK_CHROMA 1
876 ;-----------------------------------------------------------------------------
877 ; void deblock_v_chroma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
878 ;-----------------------------------------------------------------------------
879 cglobal deblock_v_chroma_%1, 5,6,8
880     CHROMA_V_START
881     mova  m0, [t5]
882     mova  m1, [t5+r1]
883     mova  m2, [r0]
884     mova  m3, [r0+r1]
885     call chroma_inter_body_%1
886     mova  [t5+r1], m1
887     mova  [r0], m2
888     CHROMA_V_LOOP 1
889     RET
890
891 ;-----------------------------------------------------------------------------
892 ; void deblock_h_chroma( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
893 ;-----------------------------------------------------------------------------
894 cglobal deblock_h_chroma_%1, 5,7,8
895     CHROMA_H_START
896     TRANSPOSE4x8W_LOAD PASS8ROWS(t5, r0, r1, t6)
897     call chroma_inter_body_%1
898     TRANSPOSE8x2W_STORE PASS8ROWS(t5, r0, r1, t6, 2)
899     CHROMA_H_LOOP 1
900     RET
901
902 ALIGN 16
903 RESET_MM_PERMUTATION
904 chroma_inter_body_%1:
905     LOAD_MASK  r2d, r3d
906     movd       m6, [r4] ; tc0
907     punpcklbw  m6, m6
908     punpcklbw  m6, m6
909     pand       m7, m6
910     DEBLOCK_P0_Q0
911     ret
912 %endmacro ; DEBLOCK_CHROMA
913
914 INIT_XMM
915 DEBLOCK_CHROMA sse2
916 %ifndef ARCH_X86_64
917 INIT_MMX
918 DEBLOCK_CHROMA mmxext
919 %endif
920
921
922 ; in: %1=p0 %2=p1 %3=q1
923 ; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2
924 %macro CHROMA_INTRA_P0 3
925     mova    m4, %1
926     pxor    m4, %3
927     pand    m4, [pb_1] ; m4 = (p0^q1)&1
928     pavgb   %1, %3
929     psubusb %1, m4
930     pavgb   %1, %2      ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1))
931 %endmacro
932
933 %define t5 r4
934 %define t6 r5
935
936 %macro DEBLOCK_CHROMA_INTRA 1
937 ;-----------------------------------------------------------------------------
938 ; void deblock_v_chroma_intra( uint8_t *pix, int stride, int alpha, int beta )
939 ;-----------------------------------------------------------------------------
940 cglobal deblock_v_chroma_intra_%1, 4,5,8
941     CHROMA_V_START
942     mova  m0, [t5]
943     mova  m1, [t5+r1]
944     mova  m2, [r0]
945     mova  m3, [r0+r1]
946     call chroma_intra_body_%1
947     mova  [t5+r1], m1
948     mova  [r0], m2
949     CHROMA_V_LOOP 0
950     RET
951
952 ;-----------------------------------------------------------------------------
953 ; void deblock_h_chroma_intra( uint8_t *pix, int stride, int alpha, int beta )
954 ;-----------------------------------------------------------------------------
955 cglobal deblock_h_chroma_intra_%1, 4,6,8
956     CHROMA_H_START
957     TRANSPOSE4x8W_LOAD  PASS8ROWS(t5, r0, r1, t6)
958     call chroma_intra_body_%1
959     TRANSPOSE8x2W_STORE PASS8ROWS(t5, r0, r1, t6, 2)
960     CHROMA_H_LOOP 0
961     RET
962
963 ALIGN 16
964 RESET_MM_PERMUTATION
965 chroma_intra_body_%1:
966     LOAD_MASK r2d, r3d
967     mova   m5, m1
968     mova   m6, m2
969     CHROMA_INTRA_P0  m1, m0, m3
970     CHROMA_INTRA_P0  m2, m3, m0
971     psubb  m1, m5
972     psubb  m2, m6
973     pand   m1, m7
974     pand   m2, m7
975     paddb  m1, m5
976     paddb  m2, m6
977     ret
978 %endmacro ; DEBLOCK_CHROMA_INTRA
979
980 INIT_XMM
981 DEBLOCK_CHROMA_INTRA sse2
982 %ifndef ARCH_X86_64
983 INIT_MMX
984 DEBLOCK_CHROMA_INTRA mmxext
985 %endif
986
987
988
989 ;-----------------------------------------------------------------------------
990 ; static void deblock_strength( uint8_t nnz[48], int8_t ref[2][40], int16_t mv[2][40][2],
991 ;                               uint8_t bs[2][4][4], int mvy_limit, int bframe )
992 ;-----------------------------------------------------------------------------
993
994 %define scan8start (4+1*8)
995 %define nnz r0+scan8start
996 %define ref r1+scan8start
997 %define mv  r2+scan8start*4
998 %define bs0 r3
999 %define bs1 r3+16
1000
1001 %macro LOAD_BYTES_MMX 1
1002     movd      m2, [%1+8*0-1]
1003     movd      m0, [%1+8*0]
1004     movd      m3, [%1+8*2-1]
1005     movd      m1, [%1+8*2]
1006     punpckldq m2, [%1+8*1-1]
1007     punpckldq m0, [%1+8*1]
1008     punpckldq m3, [%1+8*3-1]
1009     punpckldq m1, [%1+8*3]
1010 %endmacro
1011
1012 %macro DEBLOCK_STRENGTH_REFS_MMX 0
1013     LOAD_BYTES_MMX ref
1014     pxor      m2, m0
1015     pxor      m3, m1
1016     por       m2, [bs0+0]
1017     por       m3, [bs0+8]
1018     movq [bs0+0], m2
1019     movq [bs0+8], m3
1020
1021     movd      m2, [ref-8*1]
1022     movd      m3, [ref+8*1]
1023     punpckldq m2, m0  ; row -1, row 0
1024     punpckldq m3, m1  ; row  1, row 2
1025     pxor      m0, m2
1026     pxor      m1, m3
1027     por       m0, [bs1+0]
1028     por       m1, [bs1+8]
1029     movq [bs1+0], m0
1030     movq [bs1+8], m1
1031 %endmacro
1032
1033 %macro DEBLOCK_STRENGTH_MVS_MMX 2
1034     mova      m0, [mv-%2]
1035     mova      m1, [mv-%2+8]
1036     psubw     m0, [mv]
1037     psubw     m1, [mv+8]
1038     packsswb  m0, m1
1039     ABSB      m0, m1
1040     psubusb   m0, m7
1041     packsswb  m0, m0
1042     por       m0, [%1]
1043     movd    [%1], m0
1044 %endmacro
1045
1046 %macro DEBLOCK_STRENGTH_NNZ_MMX 1
1047     por       m2, m0
1048     por       m3, m1
1049     mova      m4, [%1]
1050     mova      m5, [%1+8]
1051     pminub    m2, m6
1052     pminub    m3, m6
1053     pminub    m4, m6 ; mv ? 1 : 0
1054     pminub    m5, m6
1055     paddb     m2, m2 ; nnz ? 2 : 0
1056     paddb     m3, m3
1057     pmaxub    m2, m4
1058     pmaxub    m3, m5
1059 %endmacro
1060
1061 %macro LOAD_BYTES_XMM 1
1062     movu      m0, [%1-4] ; FIXME could be aligned if we changed nnz's allocation
1063     movu      m1, [%1+12]
1064     mova      m2, m0
1065     pslldq    m0, 1
1066     shufps    m2, m1, 0xdd ; cur nnz, all rows
1067     pslldq    m1, 1
1068     shufps    m0, m1, 0xdd ; left neighbors
1069     mova      m1, m2
1070     movd      m3, [%1-8] ; could be palignr if nnz was aligned
1071     pslldq    m1, 4
1072     por       m1, m3 ; top neighbors
1073 %endmacro
1074
1075 INIT_MMX
1076 cglobal deblock_strength_mmxext, 6,6
1077     ; Prepare mv comparison register
1078     shl      r4d, 8
1079     add      r4d, 3 - (1<<8)
1080     movd      m7, r4d
1081     SPLATW    m7
1082     mova      m6, [pb_1]
1083     pxor      m0, m0
1084     mova [bs0+0], m0
1085     mova [bs0+8], m0
1086     mova [bs1+0], m0
1087     mova [bs1+8], m0
1088
1089 .lists:
1090     DEBLOCK_STRENGTH_REFS_MMX
1091     mov      r4d, 4
1092 .mvs:
1093     DEBLOCK_STRENGTH_MVS_MMX bs0, 4
1094     DEBLOCK_STRENGTH_MVS_MMX bs1, 4*8
1095     add       r2, 4*8
1096     add       r3, 4
1097     dec      r4d
1098     jg .mvs
1099     add       r1, 40
1100     add       r2, 4*8
1101     sub       r3, 16
1102     dec      r5d
1103     jge .lists
1104
1105     ; Check nnz
1106     LOAD_BYTES_MMX nnz
1107     DEBLOCK_STRENGTH_NNZ_MMX bs0
1108     ; Transpose column output
1109     SBUTTERFLY bw, 2, 3, 4
1110     SBUTTERFLY bw, 2, 3, 4
1111     mova [bs0+0], m2
1112     mova [bs0+8], m3
1113     movd      m2, [nnz-8*1]
1114     movd      m3, [nnz+8*1]
1115     punpckldq m2, m0  ; row -1, row 0
1116     punpckldq m3, m1  ; row  1, row 2
1117     DEBLOCK_STRENGTH_NNZ_MMX bs1
1118     mova [bs1+0], m2
1119     mova [bs1+8], m3
1120     RET
1121
1122 %macro DEBLOCK_STRENGTH_XMM 1
1123 cglobal deblock_strength_%1, 6,6,8
1124     ; Prepare mv comparison register
1125     shl      r4d, 8
1126     add      r4d, 3 - (1<<8)
1127     movd      m6, r4d
1128     SPLATW    m6
1129     pxor      m4, m4 ; bs0
1130     pxor      m5, m5 ; bs1
1131
1132 .lists:
1133     ; Check refs
1134     LOAD_BYTES_XMM ref
1135     pxor      m0, m2
1136     pxor      m1, m2
1137     por       m4, m0
1138     por       m5, m1
1139
1140     ; Check mvs
1141 %ifidn %1, ssse3
1142     mova      m3, [mv+4*8*0]
1143     mova      m2, [mv+4*8*1]
1144     mova      m0, m3
1145     mova      m1, m2
1146     palignr   m3, [mv+4*8*0-16], 12
1147     palignr   m2, [mv+4*8*1-16], 12
1148     psubw     m0, m3
1149     psubw     m1, m2
1150     packsswb  m0, m1
1151
1152     mova      m3, [mv+4*8*2]
1153     mova      m7, [mv+4*8*3]
1154     mova      m2, m3
1155     mova      m1, m7
1156     palignr   m3, [mv+4*8*2-16], 12
1157     palignr   m7, [mv+4*8*3-16], 12
1158     psubw     m2, m3
1159     psubw     m1, m7
1160     packsswb  m2, m1
1161 %else
1162     movu      m0, [mv-4+4*8*0]
1163     movu      m1, [mv-4+4*8*1]
1164     movu      m2, [mv-4+4*8*2]
1165     movu      m3, [mv-4+4*8*3]
1166     psubw     m0, [mv+4*8*0]
1167     psubw     m1, [mv+4*8*1]
1168     psubw     m2, [mv+4*8*2]
1169     psubw     m3, [mv+4*8*3]
1170     packsswb  m0, m1
1171     packsswb  m2, m3
1172 %endif
1173     ABSB2     m0, m2, m1, m3
1174     psubusb   m0, m6
1175     psubusb   m2, m6
1176     packsswb  m0, m2
1177     por       m4, m0
1178
1179     mova      m0, [mv+4*8*-1]
1180     mova      m1, [mv+4*8* 0]
1181     mova      m2, [mv+4*8* 1]
1182     mova      m3, [mv+4*8* 2]
1183     psubw     m0, m1
1184     psubw     m1, m2
1185     psubw     m2, m3
1186     psubw     m3, [mv+4*8* 3]
1187     packsswb  m0, m1
1188     packsswb  m2, m3
1189     ABSB2     m0, m2, m1, m3
1190     psubusb   m0, m6
1191     psubusb   m2, m6
1192     packsswb  m0, m2
1193     por       m5, m0
1194     add       r1, 40
1195     add       r2, 4*8*5
1196     dec      r5d
1197     jge .lists
1198
1199     ; Check nnz
1200     LOAD_BYTES_XMM nnz
1201     por       m0, m2
1202     por       m1, m2
1203     mova      m6, [pb_1]
1204     pminub    m0, m6
1205     pminub    m1, m6
1206     pminub    m4, m6 ; mv ? 1 : 0
1207     pminub    m5, m6
1208     paddb     m0, m0 ; nnz ? 2 : 0
1209     paddb     m1, m1
1210     pmaxub    m4, m0
1211     pmaxub    m5, m1
1212 %ifidn %1,ssse3
1213     pshufb    m4, [transpose_shuf]
1214 %else
1215     movhlps   m3, m4
1216     punpcklbw m4, m3
1217     movhlps   m3, m4
1218     punpcklbw m4, m3
1219 %endif
1220     mova   [bs1], m5
1221     mova   [bs0], m4
1222     RET
1223 %endmacro
1224
1225 INIT_XMM
1226 DEBLOCK_STRENGTH_XMM sse2
1227 %define ABSB2 ABSB2_SSSE3
1228 DEBLOCK_STRENGTH_XMM ssse3