]> git.sesse.net Git - x264/blob - common/x86/deblock-a.asm
Update file headers throughout x264
[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., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
21 ;*****************************************************************************
22
23 %include "x86inc.asm"
24
25 SECTION_RODATA
26 pb_00: times 16 db 0x00
27 pb_01: times 16 db 0x01
28 pb_03: times 16 db 0x03
29 pb_a1: times 16 db 0xa1
30
31 SECTION .text
32
33 ; expands to [base],...,[base+7*stride]
34 %define PASS8ROWS(base, base3, stride, stride3) \
35     [base], [base+stride], [base+stride*2], [base3], \
36     [base3+stride], [base3+stride*2], [base3+stride3], [base3+stride*4]
37
38 ; in: 8 rows of 4 bytes in %1..%8
39 ; out: 4 rows of 8 bytes in m0..m3
40 %macro TRANSPOSE4x8_LOAD 8
41     movd       m0, %1
42     movd       m2, %2
43     movd       m1, %3
44     movd       m3, %4
45     punpcklbw  m0, m2
46     punpcklbw  m1, m3
47     movq       m2, m0
48     punpcklwd  m0, m1
49     punpckhwd  m2, m1
50
51     movd       m4, %5
52     movd       m6, %6
53     movd       m5, %7
54     movd       m7, %8
55     punpcklbw  m4, m6
56     punpcklbw  m5, m7
57     movq       m6, m4
58     punpcklwd  m4, m5
59     punpckhwd  m6, m5
60
61     movq       m1, m0
62     movq       m3, m2
63     punpckldq  m0, m4
64     punpckhdq  m1, m4
65     punpckldq  m2, m6
66     punpckhdq  m3, m6
67 %endmacro
68
69 ; in: 4 rows of 8 bytes in m0..m3
70 ; out: 8 rows of 4 bytes in %1..%8
71 %macro TRANSPOSE8x4_STORE 8
72     movq       m4, m0
73     movq       m5, m1
74     movq       m6, m2
75     punpckhdq  m4, m4
76     punpckhdq  m5, m5
77     punpckhdq  m6, m6
78
79     punpcklbw  m0, m1
80     punpcklbw  m2, m3
81     movq       m1, m0
82     punpcklwd  m0, m2
83     punpckhwd  m1, m2
84     movd       %1, m0
85     punpckhdq  m0, m0
86     movd       %2, m0
87     movd       %3, m1
88     punpckhdq  m1, m1
89     movd       %4, m1
90
91     punpckhdq  m3, m3
92     punpcklbw  m4, m5
93     punpcklbw  m6, m3
94     movq       m5, m4
95     punpcklwd  m4, m6
96     punpckhwd  m5, m6
97     movd       %5, m4
98     punpckhdq  m4, m4
99     movd       %6, m4
100     movd       %7, m5
101     punpckhdq  m5, m5
102     movd       %8, m5
103 %endmacro
104
105 %macro SBUTTERFLY 4
106     movq       %4, %2
107     punpckl%1  %2, %3
108     punpckh%1  %4, %3
109 %endmacro
110
111 ; in: 8 rows of 8 (only the middle 6 pels are used) in %1..%8
112 ; out: 6 rows of 8 in [%9+0*16] .. [%9+5*16]
113 %macro TRANSPOSE6x8_MEM 9
114     movq  m0, %1
115     movq  m1, %2
116     movq  m2, %3
117     movq  m3, %4
118     movq  m4, %5
119     movq  m5, %6
120     movq  m6, %7
121     SBUTTERFLY bw, m0, m1, m7
122     SBUTTERFLY bw, m2, m3, m1
123     SBUTTERFLY bw, m4, m5, m3
124     movq  [%9+0x10], m1
125     SBUTTERFLY bw, m6, %8, m5
126     SBUTTERFLY wd, m0, m2, m1
127     SBUTTERFLY wd, m4, m6, m2
128     punpckhdq m0, m4
129     movq  [%9+0x00], m0
130     SBUTTERFLY wd, m7, [%9+0x10], m6
131     SBUTTERFLY wd, m3, m5, m4
132     SBUTTERFLY dq, m7, m3, m0
133     SBUTTERFLY dq, m1, m2, m5
134     punpckldq m6, m4
135     movq  [%9+0x10], m1
136     movq  [%9+0x20], m5
137     movq  [%9+0x30], m7
138     movq  [%9+0x40], m0
139     movq  [%9+0x50], m6
140 %endmacro
141
142 ; in: 8 rows of 8 in %1..%8
143 ; out: 8 rows of 8 in %9..%16
144 %macro TRANSPOSE8x8_MEM 16
145     movq  m0, %1
146     movq  m1, %2
147     movq  m2, %3
148     movq  m3, %4
149     movq  m4, %5
150     movq  m5, %6
151     movq  m6, %7
152     SBUTTERFLY bw, m0, m1, m7
153     SBUTTERFLY bw, m2, m3, m1
154     SBUTTERFLY bw, m4, m5, m3
155     SBUTTERFLY bw, m6, %8, m5
156     movq  %9,  m3
157     SBUTTERFLY wd, m0, m2, m3
158     SBUTTERFLY wd, m4, m6, m2
159     SBUTTERFLY wd, m7, m1, m6
160     movq  %11, m2
161     movq  m2,  %9
162     SBUTTERFLY wd, m2, m5, m1
163     SBUTTERFLY dq, m0, m4, m5
164     SBUTTERFLY dq, m7, m2, m4
165     movq  %9,  m0
166     movq  %10, m5
167     movq  %13, m7
168     movq  %14, m4
169     SBUTTERFLY dq, m3, %11, m0
170     SBUTTERFLY dq, m6, m1, m5
171     movq  %11, m3
172     movq  %12, m0
173     movq  %15, m6
174     movq  %16, m5
175 %endmacro
176
177 ; out: %4 = |%1-%2|>%3
178 ; clobbers: %5
179 %macro DIFF_GT 5
180     mova    %5, %2
181     mova    %4, %1
182     psubusb %5, %1
183     psubusb %4, %2
184     por     %4, %5
185     psubusb %4, %3
186 %endmacro
187
188 ; out: %4 = |%1-%2|>%3
189 ; clobbers: %5
190 %macro DIFF_GT2 5
191     mova    %5, %2
192     mova    %4, %1
193     psubusb %5, %1
194     psubusb %4, %2
195     psubusb %5, %3
196     psubusb %4, %3
197     pcmpeqb %4, %5
198 %endmacro
199
200 %macro SPLATW 1
201 %ifidn m0, xmm0
202     pshuflw  %1, %1, 0
203     movlhps  %1, %1
204 %else
205     pshufw   %1, %1, 0
206 %endif
207 %endmacro
208
209 ; in: m0=p1 m1=p0 m2=q0 m3=q1 %1=alpha-1 %2=beta-1
210 ; out: m5=beta-1, m7=mask, %3=alpha-1
211 ; clobbers: m4,m6
212 %macro LOAD_MASK 2-3
213     movd     m4, %1
214     movd     m5, %2
215     SPLATW   m4
216     SPLATW   m5
217     packuswb m4, m4  ; 16x alpha-1
218     packuswb m5, m5  ; 16x beta-1
219 %if %0>2
220     mova     %3, m4
221 %endif
222     DIFF_GT  m1, m2, m4, m7, m6 ; |p0-q0| > alpha-1
223     DIFF_GT  m0, m1, m5, m4, m6 ; |p1-p0| > beta-1
224     por      m7, m4
225     DIFF_GT  m3, m2, m5, m4, m6 ; |q1-q0| > beta-1
226     por      m7, m4
227     pxor     m6, m6
228     pcmpeqb  m7, m6
229 %endmacro
230
231 ; in: m0=p1 m1=p0 m2=q0 m3=q1 m7=(tc&mask)
232 ; out: m1=p0' m2=q0'
233 ; clobbers: m0,3-6
234 %macro DEBLOCK_P0_Q0 0
235     mova    m5, m1
236     pxor    m5, m2           ; p0^q0
237     pand    m5, [pb_01 GLOBAL] ; (p0^q0)&1
238     pcmpeqb m4, m4
239     pxor    m3, m4
240     pavgb   m3, m0           ; (p1 - q1 + 256)>>1
241     pavgb   m3, [pb_03 GLOBAL] ; (((p1 - q1 + 256)>>1)+4)>>1 = 64+2+(p1-q1)>>2
242     pxor    m4, m1
243     pavgb   m4, m2           ; (q0 - p0 + 256)>>1
244     pavgb   m3, m5
245     paddusb m3, m4           ; d+128+33
246     mova    m6, [pb_a1 GLOBAL]
247     psubusb m6, m3
248     psubusb m3, [pb_a1 GLOBAL]
249     pminub  m6, m7
250     pminub  m3, m7
251     psubusb m1, m6
252     psubusb m2, m3
253     paddusb m1, m3
254     paddusb m2, m6
255 %endmacro
256
257 ; in: m1=p0 m2=q0
258 ;     %1=p1 %2=q2 %3=[q2] %4=[q1] %5=tc0 %6=tmp
259 ; out: [q1] = clip( (q2+((p0+q0+1)>>1))>>1, q1-tc0, q1+tc0 )
260 ; clobbers: q2, tmp, tc0
261 %macro LUMA_Q1 6
262     mova    %6, m1
263     pavgb   %6, m2
264     pavgb   %2, %6             ; avg(p2,avg(p0,q0))
265     pxor    %6, %3
266     pand    %6, [pb_01 GLOBAL] ; (p2^avg(p0,q0))&1
267     psubusb %2, %6             ; (p2+((p0+q0+1)>>1))>>1
268     mova    %6, %1
269     psubusb %6, %5
270     paddusb %5, %1
271     pmaxub  %2, %6
272     pminub  %2, %5
273     mova    %4, %2
274 %endmacro
275
276 %ifdef ARCH_X86_64
277 ;-----------------------------------------------------------------------------
278 ; void x264_deblock_v_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
279 ;-----------------------------------------------------------------------------
280 INIT_XMM
281 cglobal x264_deblock_v_luma_sse2
282     movd    m8, [r4] ; tc0
283     lea     r4, [r1*3]
284     dec     r2d        ; alpha-1
285     neg     r4
286     dec     r3d        ; beta-1
287     add     r4, r0     ; pix-3*stride
288
289     mova    m0, [r4+r1]   ; p1
290     mova    m1, [r4+2*r1] ; p0
291     mova    m2, [r0]      ; q0
292     mova    m3, [r0+r1]   ; q1
293     LOAD_MASK r2d, r3d
294
295     punpcklbw m8, m8
296     punpcklbw m8, m8 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
297     pcmpeqb m9, m9
298     pcmpeqb m9, m8
299     pandn   m9, m7
300     pand    m8, m9
301
302     movdqa  m3, [r4] ; p2
303     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
304     pand    m6, m9
305     mova    m7, m8
306     psubb   m7, m6
307     pand    m6, m8
308     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
309
310     movdqa  m4, [r0+2*r1] ; q2
311     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
312     pand    m6, m9
313     pand    m8, m6
314     psubb   m7, m6
315     mova    m3, [r0+r1]
316     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m8, m6
317
318     DEBLOCK_P0_Q0
319     mova    [r4+2*r1], m1
320     mova    [r0], m2
321     ret
322
323 ;-----------------------------------------------------------------------------
324 ; void x264_deblock_h_luma_sse2( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
325 ;-----------------------------------------------------------------------------
326 INIT_MMX
327 cglobal x264_deblock_h_luma_sse2
328     movsxd r10, esi
329     lea    r11, [r10+r10*2]
330     lea    rax, [r0-4]
331     lea    r9,  [r0-4+r11]
332     sub    rsp, 0x68
333     %define pix_tmp rsp
334
335     ; transpose 6x16 -> tmp space
336     TRANSPOSE6x8_MEM  PASS8ROWS(rax, r9, r10, r11), pix_tmp
337     lea    rax, [rax+r10*8]
338     lea    r9,  [r9 +r10*8]
339     TRANSPOSE6x8_MEM  PASS8ROWS(rax, r9, r10, r11), pix_tmp+8
340
341     ; vertical filter
342     ; alpha, beta, tc0 are still in r2d, r3d, r4
343     ; don't backup rax, r9, r10, r11 because x264_deblock_v_luma_sse2 doesn't use them
344     lea    r0, [pix_tmp+0x30]
345     mov    esi, 0x10
346     call   x264_deblock_v_luma_sse2
347
348     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
349     add    rax, 2
350     add    r9,  2
351     movq   m0, [pix_tmp+0x18]
352     movq   m1, [pix_tmp+0x28]
353     movq   m2, [pix_tmp+0x38]
354     movq   m3, [pix_tmp+0x48]
355     TRANSPOSE8x4_STORE  PASS8ROWS(rax, r9, r10, r11)
356
357     shl    r10, 3
358     sub    rax, r10
359     sub    r9,  r10
360     shr    r10, 3
361     movq   m0, [pix_tmp+0x10]
362     movq   m1, [pix_tmp+0x20]
363     movq   m2, [pix_tmp+0x30]
364     movq   m3, [pix_tmp+0x40]
365     TRANSPOSE8x4_STORE  PASS8ROWS(rax, r9, r10, r11)
366
367     add    rsp, 0x68
368     ret
369
370 %else
371
372 %macro DEBLOCK_LUMA 3
373 ;-----------------------------------------------------------------------------
374 ; void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
375 ;-----------------------------------------------------------------------------
376 cglobal x264_deblock_%2_luma_%1, 5,5,1
377     lea     r4, [r1*3]
378     dec     r2     ; alpha-1
379     neg     r4
380     dec     r3     ; beta-1
381     add     r4, r0 ; pix-3*stride
382     %assign pad 2*%3+12-(stack_offset&15)
383     SUB     esp, pad
384
385     mova    m0, [r4+r1]   ; p1
386     mova    m1, [r4+2*r1] ; p0
387     mova    m2, [r0]      ; q0
388     mova    m3, [r0+r1]   ; q1
389     LOAD_MASK r2, r3
390
391     mov     r3, r4m
392     movd    m4, [r3] ; tc0
393     punpcklbw m4, m4
394     punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
395     mova   [esp+%3], m4 ; tc
396     pcmpeqb m3, m3
397     pcmpgtb m4, m3
398     pand    m4, m7
399     mova   [esp], m4 ; mask
400
401     mova    m3, [r4] ; p2
402     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
403     pand    m6, m4
404     pand    m4, [esp+%3] ; tc
405     mova    m7, m4
406     psubb   m7, m6
407     pand    m6, m4
408     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
409
410     mova    m4, [r0+2*r1] ; q2
411     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
412     mova    m5, [esp] ; mask
413     pand    m6, m5
414     mova    m5, [esp+%3] ; tc
415     pand    m5, m6
416     psubb   m7, m6
417     mova    m3, [r0+r1]
418     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
419
420     DEBLOCK_P0_Q0
421     mova    [r4+2*r1], m1
422     mova    [r0], m2
423     ADD     esp, pad
424     RET
425
426 ;-----------------------------------------------------------------------------
427 ; void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
428 ;-----------------------------------------------------------------------------
429 INIT_MMX
430 cglobal x264_deblock_h_luma_%1, 0,5
431     mov    r0, r0m
432     mov    r3, r1m
433     lea    r4, [r3*3]
434     sub    r0, 4
435     lea    r1, [r0+r4]
436     %assign pad 0x78-(stack_offset&15)
437     SUB    esp, pad
438 %define pix_tmp esp+12
439
440     ; transpose 6x16 -> tmp space
441     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp
442     lea    r0, [r0+r3*8]
443     lea    r1, [r1+r3*8]
444     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
445
446     ; vertical filter
447     lea    r0, [pix_tmp+0x30]
448     PUSH   dword r4m
449     PUSH   dword r3m
450     PUSH   dword r2m
451     PUSH   dword 16
452     PUSH   dword r0
453     call   x264_deblock_%2_luma_%1
454 %ifidn %2, v8
455     add    dword [esp   ], 8 ; pix_tmp+0x38
456     add    dword [esp+16], 2 ; tc0+2
457     call   x264_deblock_%2_luma_%1
458 %endif
459     ADD    esp, 20
460
461     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
462     mov    r0, r0m
463     sub    r0, 2
464     lea    r1, [r0+r4]
465
466     movq   m0, [pix_tmp+0x10]
467     movq   m1, [pix_tmp+0x20]
468     movq   m2, [pix_tmp+0x30]
469     movq   m3, [pix_tmp+0x40]
470     TRANSPOSE8x4_STORE  PASS8ROWS(r0, r1, r3, r4)
471
472     lea    r0, [r0+r3*8]
473     lea    r1, [r1+r3*8]
474     movq   m0, [pix_tmp+0x18]
475     movq   m1, [pix_tmp+0x28]
476     movq   m2, [pix_tmp+0x38]
477     movq   m3, [pix_tmp+0x48]
478     TRANSPOSE8x4_STORE  PASS8ROWS(r0, r1, r3, r4)
479
480     ADD    esp, pad
481     RET
482 %endmacro ; DEBLOCK_LUMA
483
484 INIT_MMX
485 DEBLOCK_LUMA mmxext, v8, 8
486 INIT_XMM
487 DEBLOCK_LUMA sse2, v, 16
488
489 %endif ; ARCH
490
491
492
493 %macro LUMA_INTRA_P012 4 ; p0..p3 in memory
494     mova  t0, p2
495     mova  t1, p0
496     pavgb t0, p1
497     pavgb t1, q0
498     pavgb t0, t1 ; ((p2+p1+1)/2 + (p0+q0+1)/2 + 1)/2
499     mova  t5, t1
500     mova  t2, p2
501     mova  t3, p0
502     paddb t2, p1
503     paddb t3, q0
504     paddb t2, t3
505     mova  t3, t2
506     mova  t4, t2
507     psrlw t2, 1
508     pavgb t2, mpb_00
509     pxor  t2, t0
510     pand  t2, mpb_01
511     psubb t0, t2 ; p1' = (p2+p1+p0+q0+2)/4;
512
513     mova  t1, p2
514     mova  t2, p2
515     pavgb t1, q1
516     psubb t2, q1
517     paddb t3, t3
518     psubb t3, t2 ; p2+2*p1+2*p0+2*q0+q1
519     pand  t2, mpb_01
520     psubb t1, t2
521     pavgb t1, p1
522     pavgb t1, t5 ; (((p2+q1)/2 + p1+1)/2 + (p0+q0+1)/2 + 1)/2
523     psrlw t3, 2
524     pavgb t3, mpb_00
525     pxor  t3, t1
526     pand  t3, mpb_01
527     psubb t1, t3 ; p0'a = (p2+2*p1+2*p0+2*q0+q1+4)/8
528
529     mova  t3, p0
530     mova  t2, p0
531     pxor  t3, q1
532     pavgb t2, q1
533     pand  t3, mpb_01
534     psubb t2, t3
535     pavgb t2, p1 ; p0'b = (2*p1+p0+q0+2)/4
536
537     pxor  t1, t2
538     pxor  t2, p0
539     pand  t1, mask1p
540     pand  t2, mask0
541     pxor  t1, t2
542     pxor  t1, p0
543     mova  %1, t1 ; store p0
544
545     mova  t1, %4 ; p3
546     mova  t2, t1
547     pavgb t1, p2
548     paddb t2, p2
549     pavgb t1, t0 ; (p3+p2+1)/2 + (p2+p1+p0+q0+2)/4
550     paddb t2, t2
551     paddb t2, t4 ; 2*p3+3*p2+p1+p0+q0
552     psrlw t2, 2
553     pavgb t2, mpb_00
554     pxor  t2, t1
555     pand  t2, mpb_01
556     psubb t1, t2 ; p2' = (2*p3+3*p2+p1+p0+q0+4)/8
557
558     pxor  t0, p1
559     pxor  t1, p2
560     pand  t0, mask1p
561     pand  t1, mask1p
562     pxor  t0, p1
563     pxor  t1, p2
564     mova  %2, t0 ; store p1
565     mova  %3, t1 ; store p2
566 %endmacro
567
568 %macro LUMA_INTRA_SWAP_PQ 0
569     %define q1 m0
570     %define q0 m1
571     %define p0 m2
572     %define p1 m3
573     %define p2 q2
574     %define mask1p mask1q
575 %endmacro
576
577 %macro DEBLOCK_LUMA_INTRA 2
578     %define p1 m0
579     %define p0 m1
580     %define q0 m2
581     %define q1 m3
582     %define t0 m4
583     %define t1 m5
584     %define t2 m6
585     %define t3 m7
586 %ifdef ARCH_X86_64
587     %define p2 m8
588     %define q2 m9
589     %define t4 m10
590     %define t5 m11
591     %define mask0 m12
592     %define mask1p m13
593     %define mask1q [rsp-24]
594     %define mpb_00 m14
595     %define mpb_01 m15
596 %else
597     %define spill(x) [esp+16*x+((stack_offset+4)&15)]
598     %define p2 [r4+r1]
599     %define q2 [r0+2*r1]
600     %define t4 spill(0)
601     %define t5 spill(1)
602     %define mask0 spill(2)
603     %define mask1p spill(3)
604     %define mask1q spill(4)
605     %define mpb_00 [pb_00 GLOBAL]
606     %define mpb_01 [pb_01 GLOBAL]
607 %endif
608
609 ;-----------------------------------------------------------------------------
610 ; void x264_deblock_v_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta )
611 ;-----------------------------------------------------------------------------
612 cglobal x264_deblock_%2_luma_intra_%1, 4,6,1
613 %ifndef ARCH_X86_64
614     sub     esp, 0x60
615 %endif
616     lea     r4, [r1*4]
617     lea     r5, [r1*3] ; 3*stride
618     dec     r2d        ; alpha-1
619     jl .end
620     neg     r4
621     dec     r3d        ; beta-1
622     jl .end
623     add     r4, r0     ; pix-4*stride
624     mova    p1, [r4+2*r1]
625     mova    p0, [r4+r5]
626     mova    q0, [r0]
627     mova    q1, [r0+r1]
628 %ifdef ARCH_X86_64
629     pxor    mpb_00, mpb_00
630     mova    mpb_01, [pb_01 GLOBAL]
631     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
632     SWAP    7, 12 ; m12=mask0
633     pavgb   t5, mpb_00
634     pavgb   t5, mpb_01 ; alpha/4+1
635     movdqa  p2, [r4+r1]
636     movdqa  q2, [r0+2*r1]
637     DIFF_GT2 p0, q0, t5, t0, t3 ; t0 = |p0-q0| > alpha/4+1
638     DIFF_GT2 p0, p2, m5, t2, t5 ; mask1 = |p2-p0| > beta-1
639     DIFF_GT2 q0, q2, m5, t4, t5 ; t4 = |q2-q0| > beta-1
640     pand    t0, mask0
641     pand    t4, t0
642     pand    t2, t0
643     mova    mask1q, t4
644     mova    mask1p, t2
645 %else
646     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
647     mova    m4, t5
648     mova    mask0, m7
649     pavgb   m4, [pb_00 GLOBAL]
650     pavgb   m4, [pb_01 GLOBAL] ; alpha/4+1
651     DIFF_GT2 p0, q0, m4, m6, m7 ; m6 = |p0-q0| > alpha/4+1
652     pand    m6, mask0
653     DIFF_GT2 p0, p2, m5, m4, m7 ; m4 = |p2-p0| > beta-1
654     pand    m4, m6
655     mova    mask1p, m4
656     DIFF_GT2 q0, q2, m5, m4, m7 ; m4 = |q2-q0| > beta-1
657     pand    m4, m6
658     mova    mask1q, m4
659 %endif
660     LUMA_INTRA_P012 [r4+r5], [r4+2*r1], [r4+r1], [r4]
661     LUMA_INTRA_SWAP_PQ
662     LUMA_INTRA_P012 [r0], [r0+r1], [r0+2*r1], [r0+r5]
663 .end:
664 %ifndef ARCH_X86_64
665     add     esp, 0x60
666 %endif
667     RET
668
669 INIT_MMX
670 %ifdef ARCH_X86_64
671 ;-----------------------------------------------------------------------------
672 ; void x264_deblock_h_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta )
673 ;-----------------------------------------------------------------------------
674 cglobal x264_deblock_h_luma_intra_%1
675     movsxd r10, r1d
676     lea    r11, [r10*3]
677     lea    rax, [r0-4]
678     lea    r9,  [r0-4+r11]
679     sub    rsp, 0x88
680     %define pix_tmp rsp
681
682     ; transpose 8x16 -> tmp space
683     TRANSPOSE8x8_MEM  PASS8ROWS(rax, r9, r10, r11), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
684     lea    rax, [rax+r10*8]
685     lea    r9,  [r9+r10*8]
686     TRANSPOSE8x8_MEM  PASS8ROWS(rax, r9, r10, r11), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
687
688     lea    r0,  [pix_tmp+0x40]
689     mov    r1,  0x10
690     call   x264_deblock_v_luma_intra_%1
691
692     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
693     lea    r9, [rax+r11]
694     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(rax, r9, r10, r11)
695     shl    r10, 3
696     sub    rax, r10
697     sub    r9,  r10
698     shr    r10, 3
699     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(rax, r9, r10, r11)
700     add    rsp, 0x88
701     ret
702 %else
703 cglobal x264_deblock_h_luma_intra_%1, 2,4
704     lea    r3,  [r1*3]
705     sub    r0,  4
706     lea    r2,  [r0+r3]
707 %assign pad 0x8c-(stack_offset&15)
708     SUB    rsp, pad
709     %define pix_tmp rsp
710
711     ; transpose 8x16 -> tmp space
712     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
713     lea    r0,  [r0+r1*8]
714     lea    r2,  [r2+r1*8]
715     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
716
717     lea    r0,  [pix_tmp+0x40]
718     PUSH   dword r3m
719     PUSH   dword r2m
720     PUSH   dword 16
721     PUSH   r0
722     call   x264_deblock_%2_luma_intra_%1
723 %ifidn %2, v8
724     add    dword [rsp], 8 ; pix_tmp+8
725     call   x264_deblock_%2_luma_intra_%1
726 %endif
727     ADD    esp, 16
728
729     mov    r1,  r1m
730     mov    r0,  r0m
731     lea    r3,  [r1*3]
732     sub    r0,  4
733     lea    r2,  [r0+r3]
734     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
735     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
736     lea    r0,  [r0+r1*8]
737     lea    r2,  [r2+r1*8]
738     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
739     ADD    rsp, pad
740     RET
741 %endif ; ARCH_X86_64
742 %endmacro ; DEBLOCK_LUMA_INTRA
743
744 INIT_XMM
745 DEBLOCK_LUMA_INTRA sse2, v
746 %ifndef ARCH_X86_64
747 INIT_MMX
748 DEBLOCK_LUMA_INTRA mmxext, v8
749 %endif
750
751
752
753 INIT_MMX
754
755 %macro CHROMA_V_START 0
756     dec    r2d      ; alpha-1
757     dec    r3d      ; beta-1
758     mov    t5, r0
759     sub    t5, r1
760     sub    t5, r1
761 %endmacro
762
763 %macro CHROMA_H_START 0
764     dec    r2d
765     dec    r3d
766     sub    r0, 2
767     lea    t6, [r1*3]
768     mov    t5, r0
769     add    r0, t6
770 %endmacro
771
772 %define t5 r5
773 %define t6 r6
774
775 ;-----------------------------------------------------------------------------
776 ; void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
777 ;-----------------------------------------------------------------------------
778 cglobal x264_deblock_v_chroma_mmxext, 5,6
779     CHROMA_V_START
780     movq  m0, [t5]
781     movq  m1, [t5+r1]
782     movq  m2, [r0]
783     movq  m3, [r0+r1]
784     call chroma_inter_body_mmxext
785     movq  [t5+r1], m1
786     movq  [r0], m2
787     RET
788
789 ;-----------------------------------------------------------------------------
790 ; void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
791 ;-----------------------------------------------------------------------------
792 cglobal x264_deblock_h_chroma_mmxext, 5,7
793 %ifdef ARCH_X86_64
794     %define buf0 [rsp-24]
795     %define buf1 [rsp-16]
796 %else
797     %define buf0 r0m
798     %define buf1 r2m
799 %endif
800     CHROMA_H_START
801     TRANSPOSE4x8_LOAD  PASS8ROWS(t5, r0, r1, t6)
802     movq  buf0, m0
803     movq  buf1, m3
804     call chroma_inter_body_mmxext
805     movq  m0, buf0
806     movq  m3, buf1
807     TRANSPOSE8x4_STORE PASS8ROWS(t5, r0, r1, t6)
808     RET
809
810 ALIGN 16
811 chroma_inter_body_mmxext:
812     LOAD_MASK  r2d, r3d
813     movd       m6, [r4] ; tc0
814     punpcklbw  m6, m6
815     pand       m7, m6
816     picgetgot r4
817     DEBLOCK_P0_Q0
818     ret
819
820
821
822 ; in: %1=p0 %2=p1 %3=q1
823 ; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2
824 %macro CHROMA_INTRA_P0 3
825     movq    m4, %1
826     pxor    m4, %3
827     pand    m4, [pb_01 GLOBAL] ; m4 = (p0^q1)&1
828     pavgb   %1, %3
829     psubusb %1, m4
830     pavgb   %1, %2             ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1))
831 %endmacro
832
833 %define t5 r4
834 %define t6 r5
835
836 ;-----------------------------------------------------------------------------
837 ; void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
838 ;-----------------------------------------------------------------------------
839 cglobal x264_deblock_v_chroma_intra_mmxext, 4,5
840     CHROMA_V_START
841     movq  m0, [t5]
842     movq  m1, [t5+r1]
843     movq  m2, [r0]
844     movq  m3, [r0+r1]
845     call chroma_intra_body_mmxext
846     movq  [t5+r1], m1
847     movq  [r0], m2
848     RET
849
850 ;-----------------------------------------------------------------------------
851 ; void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
852 ;-----------------------------------------------------------------------------
853 cglobal x264_deblock_h_chroma_intra_mmxext, 4,6
854     CHROMA_H_START
855     TRANSPOSE4x8_LOAD  PASS8ROWS(t5, r0, r1, t6)
856     call chroma_intra_body_mmxext
857     TRANSPOSE8x4_STORE PASS8ROWS(t5, r0, r1, t6)
858     RET
859
860 ALIGN 16
861 chroma_intra_body_mmxext:
862     LOAD_MASK r2d, r3d
863     movq   m5, m1
864     movq   m6, m2
865     picgetgot r2
866     CHROMA_INTRA_P0  m1, m0, m3
867     CHROMA_INTRA_P0  m2, m3, m0
868     psubb  m1, m5
869     psubb  m2, m6
870     pand   m1, m7
871     pand   m2, m7
872     paddb  m1, m5
873     paddb  m2, m6
874     ret