]> git.sesse.net Git - x264/blob - common/x86/deblock-a.asm
force unroll macroblock_load_pic_pointers
[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 ;*
8 ;* This program is free software; you can redistribute it and/or modify
9 ;* it under the terms of the GNU General Public License as published by
10 ;* the Free Software Foundation; either version 2 of the License, or
11 ;* (at your option) any later version.
12 ;*
13 ;* This program is distributed in the hope that it will be useful,
14 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;* GNU General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU General Public License
19 ;* along with this program; if not, write to the Free Software
20 ;* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21 ;*****************************************************************************
22
23 %include "x86inc.asm"
24
25 SECTION_RODATA
26 pb_01: times 16 db 0x01
27 pb_03: times 16 db 0x03
28 pb_a1: times 16 db 0xa1
29
30 SECTION .text
31
32 ; expands to [base],...,[base+7*stride]
33 %define PASS8ROWS(base, base3, stride, stride3) \
34     [base], [base+stride], [base+stride*2], [base3], \
35     [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
36
37 ; in: 8 rows of 4 bytes in %1..%8
38 ; out: 4 rows of 8 bytes in m0..m3
39 %macro TRANSPOSE4x8_LOAD 8
40     movd       m0, %1
41     movd       m2, %2
42     movd       m1, %3
43     movd       m3, %4
44     punpcklbw  m0, m2
45     punpcklbw  m1, m3
46     movq       m2, m0
47     punpcklwd  m0, m1
48     punpckhwd  m2, m1
49
50     movd       m4, %5
51     movd       m6, %6
52     movd       m5, %7
53     movd       m7, %8
54     punpcklbw  m4, m6
55     punpcklbw  m5, m7
56     movq       m6, m4
57     punpcklwd  m4, m5
58     punpckhwd  m6, m5
59
60     movq       m1, m0
61     movq       m3, m2
62     punpckldq  m0, m4
63     punpckhdq  m1, m4
64     punpckldq  m2, m6
65     punpckhdq  m3, m6
66 %endmacro
67
68 ; in: 4 rows of 8 bytes in m0..m3
69 ; out: 8 rows of 4 bytes in %1..%8
70 %macro TRANSPOSE8x4_STORE 8
71     movq       m4, m0
72     movq       m5, m1
73     movq       m6, m2
74     punpckhdq  m4, m4
75     punpckhdq  m5, m5
76     punpckhdq  m6, m6
77
78     punpcklbw  m0, m1
79     punpcklbw  m2, m3
80     movq       m1, m0
81     punpcklwd  m0, m2
82     punpckhwd  m1, m2
83     movd       %1, m0
84     punpckhdq  m0, m0
85     movd       %2, m0
86     movd       %3, m1
87     punpckhdq  m1, m1
88     movd       %4, m1
89
90     punpckhdq  m3, m3
91     punpcklbw  m4, m5
92     punpcklbw  m6, m3
93     movq       m5, m4
94     punpcklwd  m4, m6
95     punpckhwd  m5, m6
96     movd       %5, m4
97     punpckhdq  m4, m4
98     movd       %6, m4
99     movd       %7, m5
100     punpckhdq  m5, m5
101     movd       %8, m5
102 %endmacro
103
104 %macro SBUTTERFLY 4
105     movq       %4, %2
106     punpckl%1  %2, %3
107     punpckh%1  %4, %3
108 %endmacro
109
110 ; in: 8 rows of 8 (only the middle 6 pels are used) in %1..%8
111 ; out: 6 rows of 8 in [%9+0*16] .. [%9+5*16]
112 %macro TRANSPOSE6x8_MEM 9
113     movq  m0, %1
114     movq  m1, %3
115     movq  m2, %5
116     movq  m3, %7
117     SBUTTERFLY bw, m0, %2, m4
118     SBUTTERFLY bw, m1, %4, m5
119     SBUTTERFLY bw, m2, %6, m6
120     movq  [%9+0x10], m5
121     SBUTTERFLY bw, m3, %8, m7
122     SBUTTERFLY wd, m0, m1, m5
123     SBUTTERFLY wd, m2, m3, m1
124     punpckhdq m0, m2
125     movq  [%9+0x00], m0
126     SBUTTERFLY wd, m4, [%9+0x10], m3
127     SBUTTERFLY wd, m6, m7, m2
128     SBUTTERFLY dq, m4, m6, m0
129     SBUTTERFLY dq, m5, m1, m7
130     punpckldq m3, m2
131     movq  [%9+0x10], m5
132     movq  [%9+0x20], m7
133     movq  [%9+0x30], m4
134     movq  [%9+0x40], m0
135     movq  [%9+0x50], m3
136 %endmacro
137
138 ; out: %4 = |%1-%2|>%3
139 ; clobbers: %5
140 %macro DIFF_GT 5
141     mova    %5, %2
142     mova    %4, %1
143     psubusb %5, %1
144     psubusb %4, %2
145     por     %4, %5
146     psubusb %4, %3
147 %endmacro
148
149 ; out: %4 = |%1-%2|>%3
150 ; clobbers: %5
151 %macro DIFF_GT2 5
152     mova    %5, %2
153     mova    %4, %1
154     psubusb %5, %1
155     psubusb %4, %2
156     psubusb %5, %3
157     psubusb %4, %3
158     pcmpeqb %4, %5
159 %endmacro
160
161 %macro SPLATW 1
162 %ifidn m0, xmm0
163     pshuflw  %1, %1, 0
164     punpcklqdq %1, %1
165 %else
166     pshufw   %1, %1, 0
167 %endif
168 %endmacro
169
170 ; in: m0=p1 m1=p0 m2=q0 m3=q1 %1=alpha-1 %2=beta-1
171 ; out: m5=beta-1, m7=mask
172 ; clobbers: m4,m6
173 %macro LOAD_MASK 2
174     movd     m4, %1
175     movd     m5, %2
176     SPLATW   m4
177     SPLATW   m5
178     packuswb m4, m4  ; 16x alpha-1
179     packuswb m5, m5  ; 16x beta-1
180     DIFF_GT  m1, m2, m4, m7, m6 ; |p0-q0| > alpha-1
181     DIFF_GT  m0, m1, m5, m4, m6 ; |p1-p0| > beta-1
182     por      m7, m4
183     DIFF_GT  m3, m2, m5, m4, m6 ; |q1-q0| > beta-1
184     por      m7, m4
185     pxor     m6, m6
186     pcmpeqb  m7, m6
187 %endmacro
188
189 ; in: m0=p1 m1=p0 m2=q0 m3=q1 m7=(tc&mask)
190 ; out: m1=p0' m2=q0'
191 ; clobbers: m0,3-6
192 %macro DEBLOCK_P0_Q0 0
193     mova    m5, m1
194     pxor    m5, m2           ; p0^q0
195     pand    m5, [pb_01 GLOBAL] ; (p0^q0)&1
196     pcmpeqb m4, m4
197     pxor    m3, m4
198     pavgb   m3, m0           ; (p1 - q1 + 256)>>1
199     pavgb   m3, [pb_03 GLOBAL] ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2
200     pxor    m4, m1
201     pavgb   m4, m2           ; (q0 - p0 + 256)>>1
202     pavgb   m3, m5
203     paddusb m3, m4           ; d+128+33
204     mova    m6, [pb_a1 GLOBAL]
205     psubusb m6, m3
206     psubusb m3, [pb_a1 GLOBAL]
207     pminub  m6, m7
208     pminub  m3, m7
209     psubusb m1, m6
210     psubusb m2, m3
211     paddusb m1, m3
212     paddusb m2, m6
213 %endmacro
214
215 ; in: m1=p0 m2=q0
216 ;     %1=p1 %2=q2 %3=[q2] %4=[q1] %5=tc0 %6=tmp
217 ; out: [q1] = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 )
218 ; clobbers: q2, tmp, tc0
219 %macro LUMA_Q1 6
220     mova    %6, m1
221     pavgb   %6, m2
222     pavgb   %2, %6             ; avg(p2,avg(p0,q0))
223     pxor    %6, %3
224     pand    %6, [pb_01 GLOBAL] ; (p2^avg(p0,q0))&1
225     psubusb %2, %6             ; (p2+((p0+q0+1)>>1))>>1
226     mova    %6, %1
227     psubusb %6, %5
228     paddusb %5, %1
229     pmaxub  %2, %6
230     pminub  %2, %5
231     mova    %4, %2
232 %endmacro
233
234 ;-----------------------------------------------------------------------------
235 ; void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
236 ;-----------------------------------------------------------------------------
237 %ifdef ARCH_X86_64
238 INIT_XMM
239 cglobal x264_deblock_v_luma_sse2
240     movd    m8, [r4] ; tc0
241     lea     r4, [r1*3]
242     dec     r2d        ; alpha-1
243     neg     r4
244     dec     r3d        ; beta-1
245     add     r4, r0     ; pix-3*stride
246
247     mova    m0, [r4+r1]   ; p1
248     mova    m1, [r4+2*r1] ; p0
249     mova    m2, [r0]      ; q0
250     mova    m3, [r0+r1]   ; q1
251     LOAD_MASK r2d, r3d
252
253     punpcklbw m8, m8
254     punpcklbw m8, m8 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
255     pcmpeqb m9, m9
256     pcmpeqb m9, m8
257     pandn   m9, m7
258     pand    m8, m9
259
260     movdqa  m3, [r4] ; p2
261     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
262     pand    m6, m9
263     mova    m7, m8
264     psubb   m7, m6
265     pand    m6, m8
266     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
267
268     movdqa  m4, [r0+2*r1] ; q2
269     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
270     pand    m6, m9
271     pand    m8, m6
272     psubb   m7, m6
273     mova    m3, [r0+r1]
274     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m8, m6
275
276     DEBLOCK_P0_Q0
277     mova    [r4+2*r1], m1
278     mova    [r0], m2
279     ret
280
281 ;-----------------------------------------------------------------------------
282 ; void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
283 ;-----------------------------------------------------------------------------
284 INIT_MMX
285 cglobal x264_deblock_h_luma_sse2
286     movsxd r10, esi
287     lea    r11, [r10+r10*2]
288     lea    rax, [r0-4]
289     lea    r9,  [r0-4+r11]
290     sub    rsp, 0x68
291     %define pix_tmp rsp
292
293     ; transpose 6x16 -> tmp space
294     TRANSPOSE6x8_MEM  PASS8ROWS(rax, r9, r10, r11), pix_tmp
295     lea    rax, [rax+r10*8]
296     lea    r9,  [r9 +r10*8]
297     TRANSPOSE6x8_MEM  PASS8ROWS(rax, r9, r10, r11), pix_tmp+8
298
299     ; vertical filter
300     ; alpha, beta, tc0 are still in r2d, r3d, r4
301     ; don't backup rax, r9, r10, r11 because x264_deblock_v_luma_sse2 doesn't use them
302     lea    r0, [pix_tmp+0x30]
303     mov    esi, 0x10
304     call   x264_deblock_v_luma_sse2
305
306     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
307     add    rax, 2
308     add    r9,  2
309     movq   m0, [pix_tmp+0x18]
310     movq   m1, [pix_tmp+0x28]
311     movq   m2, [pix_tmp+0x38]
312     movq   m3, [pix_tmp+0x48]
313     TRANSPOSE8x4_STORE  PASS8ROWS(rax, r9, r10, r11)
314
315     shl    r10, 3
316     sub    rax, r10
317     sub    r9,  r10
318     shr    r10, 3
319     movq   m0, [pix_tmp+0x10]
320     movq   m1, [pix_tmp+0x20]
321     movq   m2, [pix_tmp+0x30]
322     movq   m3, [pix_tmp+0x40]
323     TRANSPOSE8x4_STORE  PASS8ROWS(rax, r9, r10, r11)
324
325     add    rsp, 0x68
326     ret
327
328 %else
329
330 %macro DEBLOCK_LUMA 3
331 ;-----------------------------------------------------------------------------
332 ; void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
333 ;-----------------------------------------------------------------------------
334 cglobal x264_deblock_%2_luma_%1, 5,5,1
335     lea     r4, [r1*3]
336     dec     r2     ; alpha-1
337     neg     r4
338     dec     r3     ; beta-1
339     add     r4, r0 ; pix-3*stride
340
341     mova    m0, [r4+r1]   ; p1
342     mova    m1, [r4+2*r1] ; p0
343     mova    m2, [r0]      ; q0
344     mova    m3, [r0+r1]   ; q1
345     LOAD_MASK r2, r3
346
347     mov     r3, r4m
348 %if %3 == 16
349     mov     r2, esp
350     and     esp, -16
351     sub     esp, 32
352 %else
353     sub     esp, 16
354 %endif
355
356     movd    m4, [r3] ; tc0
357     punpcklbw m4, m4
358     punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
359     mova   [esp+%3], m4 ; tc
360     pcmpeqb m3, m3
361     pcmpgtb m4, m3
362     pand    m4, m7
363     mova   [esp], m4 ; mask
364
365     mova    m3, [r4] ; p2
366     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
367     pand    m6, m4
368     pand    m4, [esp+%3] ; tc
369     mova    m7, m4
370     psubb   m7, m6
371     pand    m6, m4
372     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
373
374     mova    m4, [r0+2*r1] ; q2
375     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
376     mova    m5, [esp] ; mask
377     pand    m6, m5
378     mova    m5, [esp+%3] ; tc
379     pand    m5, m6
380     psubb   m7, m6
381     mova    m3, [r0+r1]
382     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
383
384     DEBLOCK_P0_Q0
385     mova    [r4+2*r1], m1
386     mova    [r0], m2
387
388 %if %3 == 16
389     mov     esp, r2
390 %else
391     add     esp, 16
392 %endif
393     RET
394
395 ;-----------------------------------------------------------------------------
396 ; void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
397 ;-----------------------------------------------------------------------------
398 INIT_MMX
399 cglobal x264_deblock_h_luma_%1, 0,6
400     mov    r0, r0m
401     mov    r3, r1m
402     lea    r4, [r3*3]
403     sub    r0, 4
404     lea    r1, [r0+r4]
405     SUB    esp, 0x6c
406     lea    r5, [esp+12]
407     and    r5, -16
408 %define pix_tmp r5
409
410     ; transpose 6x16 -> tmp space
411     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp
412     lea    r0, [r0+r3*8]
413     lea    r1, [r1+r3*8]
414     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
415
416     ; vertical filter
417     lea    r0, [pix_tmp+0x30]
418     PUSH   dword r4m
419     PUSH   dword r3m
420     PUSH   dword r2m
421     PUSH   dword 16
422     PUSH   dword r0
423     call   x264_deblock_%2_luma_%1
424 %ifidn %2, v8
425     add    dword [esp   ], 8 ; pix_tmp+0x38
426     add    dword [esp+16], 2 ; tc0+2
427     call   x264_deblock_%2_luma_%1
428 %endif
429     ADD    esp, 20
430
431     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
432     mov    r0, r0m
433     sub    r0, 2
434     lea    r1, [r0+r4]
435
436     movq   m0, [pix_tmp+0x10]
437     movq   m1, [pix_tmp+0x20]
438     movq   m2, [pix_tmp+0x30]
439     movq   m3, [pix_tmp+0x40]
440     TRANSPOSE8x4_STORE  PASS8ROWS(r0, r1, r3, r4)
441
442     lea    r0, [r0+r3*8]
443     lea    r1, [r1+r3*8]
444     movq   m0, [pix_tmp+0x18]
445     movq   m1, [pix_tmp+0x28]
446     movq   m2, [pix_tmp+0x38]
447     movq   m3, [pix_tmp+0x48]
448     TRANSPOSE8x4_STORE  PASS8ROWS(r0, r1, r3, r4)
449
450     ADD    esp, 0x6c
451     RET
452 %endmacro ; DEBLOCK_LUMA
453
454 INIT_MMX
455 DEBLOCK_LUMA mmxext, v8, 8
456 INIT_XMM
457 DEBLOCK_LUMA sse2, v, 16
458
459 %endif ; ARCH
460
461
462
463 INIT_MMX
464
465 %macro CHROMA_V_START 0
466     dec    r2d      ; alpha-1
467     dec    r3d      ; beta-1
468     mov    t5, r0
469     sub    t5, r1
470     sub    t5, r1
471 %endmacro
472
473 %macro CHROMA_H_START 0
474     dec    r2d
475     dec    r3d
476     sub    r0, 2
477     lea    t6, [r1*3]
478     mov    t5, r0
479     add    r0, t6
480 %endmacro
481
482 %define t5 r5
483 %define t6 r6
484
485 ;-----------------------------------------------------------------------------
486 ; void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
487 ;-----------------------------------------------------------------------------
488 cglobal x264_deblock_v_chroma_mmxext, 5,6
489     CHROMA_V_START
490
491     movq  m0, [t5]
492     movq  m1, [t5+r1]
493     movq  m2, [r0]
494     movq  m3, [r0+r1]
495
496     LOAD_MASK  r2d, r3d
497     movd       m6, [r4] ; tc0
498     punpcklbw  m6, m6
499     pand       m7, m6
500     picgetgot r4
501     DEBLOCK_P0_Q0
502
503     movq  [t5+r1], m1
504     movq  [r0], m2
505     RET
506
507 ;-----------------------------------------------------------------------------
508 ; void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
509 ;-----------------------------------------------------------------------------
510 cglobal x264_deblock_h_chroma_mmxext, 5,7
511 %ifdef ARCH_X86_64
512     %define buf0 [rsp-16]
513     %define buf1 [rsp-8]
514 %else
515     %define buf0 r0m
516     %define buf1 r2m
517 %endif
518     CHROMA_H_START
519
520     TRANSPOSE4x8_LOAD  PASS8ROWS(t5, r0, r1, t6)
521     movq  buf0, m0
522     movq  buf1, m3
523
524     LOAD_MASK  r2d, r3d
525     movd       m6, [r4] ; tc0
526     punpcklbw  m6, m6
527     pand       m7, m6
528     picgetgot r4
529     DEBLOCK_P0_Q0
530
531     movq  m0, buf0
532     movq  m3, buf1
533     TRANSPOSE8x4_STORE PASS8ROWS(t5, r0, r1, t6)
534     RET
535
536
537
538 ; in: %1=p0 %2=p1 %3=q1
539 ; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2
540 %macro CHROMA_INTRA_P0 3
541     movq    m4, %1
542     pxor    m4, %3
543     pand    m4, [pb_01 GLOBAL] ; m4 = (p0^q1)&1
544     pavgb   %1, %3
545     psubusb %1, m4
546     pavgb   %1, %2             ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1))
547 %endmacro
548
549 %macro CHROMA_INTRA_BODY 0
550     LOAD_MASK r2d, r3d
551     movq   m5, m1
552     movq   m6, m2
553     CHROMA_INTRA_P0  m1, m0, m3
554     CHROMA_INTRA_P0  m2, m3, m0
555     psubb  m1, m5
556     psubb  m2, m6
557     pand   m1, m7
558     pand   m2, m7
559     paddb  m1, m5
560     paddb  m2, m6
561 %endmacro
562
563 %define t5 r4
564 %define t6 r5
565
566 ;-----------------------------------------------------------------------------
567 ; void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
568 ;-----------------------------------------------------------------------------
569 cglobal x264_deblock_v_chroma_intra_mmxext, 4,5,1
570     CHROMA_V_START
571
572     movq  m0, [t5]
573     movq  m1, [t5+r1]
574     movq  m2, [r0]
575     movq  m3, [r0+r1]
576
577     CHROMA_INTRA_BODY
578
579     movq  [t5+r1], m1
580     movq  [r0], m2
581     RET
582
583 ;-----------------------------------------------------------------------------
584 ; void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
585 ;-----------------------------------------------------------------------------
586 cglobal x264_deblock_h_chroma_intra_mmxext, 4,6,1
587     CHROMA_H_START
588     TRANSPOSE4x8_LOAD  PASS8ROWS(t5, r0, r1, t6)
589     CHROMA_INTRA_BODY
590     TRANSPOSE8x4_STORE PASS8ROWS(t5, r0, r1, t6)
591     RET
592