]> git.sesse.net Git - x264/blob - common/x86/deblock-a.asm
MMX version of 8x8 interlaced zigzag
[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     punpcklqdq %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, 5,5,10
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, 5,7
328     movsxd r10, r1d
329     lea    r11, [r10+r10*2]
330     lea    r6,  [r0-4]
331     lea    r5,  [r0-4+r11]
332 %ifdef WIN64
333     sub    rsp, 0x98
334     %define pix_tmp rsp+0x30
335 %else
336     sub    rsp, 0x68
337     %define pix_tmp rsp
338 %endif
339
340     ; transpose 6x16 -> tmp space
341     TRANSPOSE6x8_MEM  PASS8ROWS(r6, r5, r10, r11), pix_tmp
342     lea    r6, [r6+r10*8]
343     lea    r5, [r5+r10*8]
344     TRANSPOSE6x8_MEM  PASS8ROWS(r6, r5, r10, r11), pix_tmp+8
345
346     ; vertical filter
347     ; alpha, beta, tc0 are still in r2d, r3d, r4
348     ; don't backup r6, r5, r10, r11 because x264_deblock_v_luma_sse2 doesn't use them
349     lea    r0, [pix_tmp+0x30]
350     mov    r1d, 0x10
351 %ifdef WIN64
352     mov    [rsp+0x20], r4
353 %endif
354     call   x264_deblock_v_luma_sse2
355
356     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
357     add    r6, 2
358     add    r5, 2
359     movq   m0, [pix_tmp+0x18]
360     movq   m1, [pix_tmp+0x28]
361     movq   m2, [pix_tmp+0x38]
362     movq   m3, [pix_tmp+0x48]
363     TRANSPOSE8x4_STORE  PASS8ROWS(r6, r5, r10, r11)
364
365     shl    r10, 3
366     sub    r6,  r10
367     sub    r5,  r10
368     shr    r10, 3
369     movq   m0, [pix_tmp+0x10]
370     movq   m1, [pix_tmp+0x20]
371     movq   m2, [pix_tmp+0x30]
372     movq   m3, [pix_tmp+0x40]
373     TRANSPOSE8x4_STORE  PASS8ROWS(r6, r5, r10, r11)
374
375 %ifdef WIN64
376     add    rsp, 0x98
377 %else
378     add    rsp, 0x68
379 %endif
380     RET
381
382 %else
383
384 %macro DEBLOCK_LUMA 3
385 ;-----------------------------------------------------------------------------
386 ; void x264_deblock_v8_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
387 ;-----------------------------------------------------------------------------
388 cglobal x264_deblock_%2_luma_%1, 5,5
389     lea     r4, [r1*3]
390     dec     r2     ; alpha-1
391     neg     r4
392     dec     r3     ; beta-1
393     add     r4, r0 ; pix-3*stride
394     %assign pad 2*%3+12-(stack_offset&15)
395     SUB     esp, pad
396
397     mova    m0, [r4+r1]   ; p1
398     mova    m1, [r4+2*r1] ; p0
399     mova    m2, [r0]      ; q0
400     mova    m3, [r0+r1]   ; q1
401     LOAD_MASK r2, r3
402
403     mov     r3, r4mp
404     movd    m4, [r3] ; tc0
405     punpcklbw m4, m4
406     punpcklbw m4, m4 ; tc = 4x tc0[3], 4x tc0[2], 4x tc0[1], 4x tc0[0]
407     mova   [esp+%3], m4 ; tc
408     pcmpeqb m3, m3
409     pcmpgtb m4, m3
410     pand    m4, m7
411     mova   [esp], m4 ; mask
412
413     mova    m3, [r4] ; p2
414     DIFF_GT2 m1, m3, m5, m6, m7 ; |p2-p0| > beta-1
415     pand    m6, m4
416     pand    m4, [esp+%3] ; tc
417     mova    m7, m4
418     psubb   m7, m6
419     pand    m6, m4
420     LUMA_Q1 m0, m3, [r4], [r4+r1], m6, m4
421
422     mova    m4, [r0+2*r1] ; q2
423     DIFF_GT2 m2, m4, m5, m6, m3 ; |q2-q0| > beta-1
424     mova    m5, [esp] ; mask
425     pand    m6, m5
426     mova    m5, [esp+%3] ; tc
427     pand    m5, m6
428     psubb   m7, m6
429     mova    m3, [r0+r1]
430     LUMA_Q1 m3, m4, [r0+2*r1], [r0+r1], m5, m6
431
432     DEBLOCK_P0_Q0
433     mova    [r4+2*r1], m1
434     mova    [r0], m2
435     ADD     esp, pad
436     RET
437
438 ;-----------------------------------------------------------------------------
439 ; void x264_deblock_h_luma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
440 ;-----------------------------------------------------------------------------
441 INIT_MMX
442 cglobal x264_deblock_h_luma_%1, 0,5
443     mov    r0, r0mp
444     mov    r3, r1m
445     lea    r4, [r3*3]
446     sub    r0, 4
447     lea    r1, [r0+r4]
448     %assign pad 0x78-(stack_offset&15)
449     SUB    esp, pad
450 %define pix_tmp esp+12
451
452     ; transpose 6x16 -> tmp space
453     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp
454     lea    r0, [r0+r3*8]
455     lea    r1, [r1+r3*8]
456     TRANSPOSE6x8_MEM  PASS8ROWS(r0, r1, r3, r4), pix_tmp+8
457
458     ; vertical filter
459     lea    r0, [pix_tmp+0x30]
460     PUSH   dword r4m
461     PUSH   dword r3m
462     PUSH   dword r2m
463     PUSH   dword 16
464     PUSH   dword r0
465     call   x264_deblock_%2_luma_%1
466 %ifidn %2, v8
467     add    dword [esp   ], 8 ; pix_tmp+0x38
468     add    dword [esp+16], 2 ; tc0+2
469     call   x264_deblock_%2_luma_%1
470 %endif
471     ADD    esp, 20
472
473     ; transpose 16x4 -> original space  (only the middle 4 rows were changed by the filter)
474     mov    r0, r0mp
475     sub    r0, 2
476     lea    r1, [r0+r4]
477
478     movq   m0, [pix_tmp+0x10]
479     movq   m1, [pix_tmp+0x20]
480     movq   m2, [pix_tmp+0x30]
481     movq   m3, [pix_tmp+0x40]
482     TRANSPOSE8x4_STORE  PASS8ROWS(r0, r1, r3, r4)
483
484     lea    r0, [r0+r3*8]
485     lea    r1, [r1+r3*8]
486     movq   m0, [pix_tmp+0x18]
487     movq   m1, [pix_tmp+0x28]
488     movq   m2, [pix_tmp+0x38]
489     movq   m3, [pix_tmp+0x48]
490     TRANSPOSE8x4_STORE  PASS8ROWS(r0, r1, r3, r4)
491
492     ADD    esp, pad
493     RET
494 %endmacro ; DEBLOCK_LUMA
495
496 INIT_MMX
497 DEBLOCK_LUMA mmxext, v8, 8
498 INIT_XMM
499 DEBLOCK_LUMA sse2, v, 16
500
501 %endif ; ARCH
502
503
504
505 %macro LUMA_INTRA_P012 4 ; p0..p3 in memory
506     mova  t0, p2
507     mova  t1, p0
508     pavgb t0, p1
509     pavgb t1, q0
510     pavgb t0, t1 ; ((p2+p1+1)/2 + (p0+q0+1)/2 + 1)/2
511     mova  t5, t1
512     mova  t2, p2
513     mova  t3, p0
514     paddb t2, p1
515     paddb t3, q0
516     paddb t2, t3
517     mova  t3, t2
518     mova  t4, t2
519     psrlw t2, 1
520     pavgb t2, mpb_00
521     pxor  t2, t0
522     pand  t2, mpb_01
523     psubb t0, t2 ; p1' = (p2+p1+p0+q0+2)/4;
524
525     mova  t1, p2
526     mova  t2, p2
527     pavgb t1, q1
528     psubb t2, q1
529     paddb t3, t3
530     psubb t3, t2 ; p2+2*p1+2*p0+2*q0+q1
531     pand  t2, mpb_01
532     psubb t1, t2
533     pavgb t1, p1
534     pavgb t1, t5 ; (((p2+q1)/2 + p1+1)/2 + (p0+q0+1)/2 + 1)/2
535     psrlw t3, 2
536     pavgb t3, mpb_00
537     pxor  t3, t1
538     pand  t3, mpb_01
539     psubb t1, t3 ; p0'a = (p2+2*p1+2*p0+2*q0+q1+4)/8
540
541     mova  t3, p0
542     mova  t2, p0
543     pxor  t3, q1
544     pavgb t2, q1
545     pand  t3, mpb_01
546     psubb t2, t3
547     pavgb t2, p1 ; p0'b = (2*p1+p0+q0+2)/4
548
549     pxor  t1, t2
550     pxor  t2, p0
551     pand  t1, mask1p
552     pand  t2, mask0
553     pxor  t1, t2
554     pxor  t1, p0
555     mova  %1, t1 ; store p0
556
557     mova  t1, %4 ; p3
558     mova  t2, t1
559     pavgb t1, p2
560     paddb t2, p2
561     pavgb t1, t0 ; (p3+p2+1)/2 + (p2+p1+p0+q0+2)/4
562     paddb t2, t2
563     paddb t2, t4 ; 2*p3+3*p2+p1+p0+q0
564     psrlw t2, 2
565     pavgb t2, mpb_00
566     pxor  t2, t1
567     pand  t2, mpb_01
568     psubb t1, t2 ; p2' = (2*p3+3*p2+p1+p0+q0+4)/8
569
570     pxor  t0, p1
571     pxor  t1, p2
572     pand  t0, mask1p
573     pand  t1, mask1p
574     pxor  t0, p1
575     pxor  t1, p2
576     mova  %2, t0 ; store p1
577     mova  %3, t1 ; store p2
578 %endmacro
579
580 %macro LUMA_INTRA_SWAP_PQ 0
581     %define q1 m0
582     %define q0 m1
583     %define p0 m2
584     %define p1 m3
585     %define p2 q2
586     %define mask1p mask1q
587 %endmacro
588
589 %macro DEBLOCK_LUMA_INTRA 2
590     %define p1 m0
591     %define p0 m1
592     %define q0 m2
593     %define q1 m3
594     %define t0 m4
595     %define t1 m5
596     %define t2 m6
597     %define t3 m7
598 %ifdef ARCH_X86_64
599     %define p2 m8
600     %define q2 m9
601     %define t4 m10
602     %define t5 m11
603     %define mask0 m12
604     %define mask1p m13
605     %define mask1q [rsp-24]
606     %define mpb_00 m14
607     %define mpb_01 m15
608 %else
609     %define spill(x) [esp+16*x+((stack_offset+4)&15)]
610     %define p2 [r4+r1]
611     %define q2 [r0+2*r1]
612     %define t4 spill(0)
613     %define t5 spill(1)
614     %define mask0 spill(2)
615     %define mask1p spill(3)
616     %define mask1q spill(4)
617     %define mpb_00 [pb_00 GLOBAL]
618     %define mpb_01 [pb_01 GLOBAL]
619 %endif
620
621 ;-----------------------------------------------------------------------------
622 ; void x264_deblock_v_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta )
623 ;-----------------------------------------------------------------------------
624 cglobal x264_deblock_%2_luma_intra_%1, 4,6,16
625 %ifndef ARCH_X86_64
626     sub     esp, 0x60
627 %endif
628     lea     r4, [r1*4]
629     lea     r5, [r1*3] ; 3*stride
630     dec     r2d        ; alpha-1
631     jl .end
632     neg     r4
633     dec     r3d        ; beta-1
634     jl .end
635     add     r4, r0     ; pix-4*stride
636     mova    p1, [r4+2*r1]
637     mova    p0, [r4+r5]
638     mova    q0, [r0]
639     mova    q1, [r0+r1]
640 %ifdef ARCH_X86_64
641     pxor    mpb_00, mpb_00
642     mova    mpb_01, [pb_01 GLOBAL]
643     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
644     SWAP    7, 12 ; m12=mask0
645     pavgb   t5, mpb_00
646     pavgb   t5, mpb_01 ; alpha/4+1
647     movdqa  p2, [r4+r1]
648     movdqa  q2, [r0+2*r1]
649     DIFF_GT2 p0, q0, t5, t0, t3 ; t0 = |p0-q0| > alpha/4+1
650     DIFF_GT2 p0, p2, m5, t2, t5 ; mask1 = |p2-p0| > beta-1
651     DIFF_GT2 q0, q2, m5, t4, t5 ; t4 = |q2-q0| > beta-1
652     pand    t0, mask0
653     pand    t4, t0
654     pand    t2, t0
655     mova    mask1q, t4
656     mova    mask1p, t2
657 %else
658     LOAD_MASK r2d, r3d, t5 ; m5=beta-1, t5=alpha-1, m7=mask0
659     mova    m4, t5
660     mova    mask0, m7
661     pavgb   m4, [pb_00 GLOBAL]
662     pavgb   m4, [pb_01 GLOBAL] ; alpha/4+1
663     DIFF_GT2 p0, q0, m4, m6, m7 ; m6 = |p0-q0| > alpha/4+1
664     pand    m6, mask0
665     DIFF_GT2 p0, p2, m5, m4, m7 ; m4 = |p2-p0| > beta-1
666     pand    m4, m6
667     mova    mask1p, m4
668     DIFF_GT2 q0, q2, m5, m4, m7 ; m4 = |q2-q0| > beta-1
669     pand    m4, m6
670     mova    mask1q, m4
671 %endif
672     LUMA_INTRA_P012 [r4+r5], [r4+2*r1], [r4+r1], [r4]
673     LUMA_INTRA_SWAP_PQ
674     LUMA_INTRA_P012 [r0], [r0+r1], [r0+2*r1], [r0+r5]
675 .end:
676 %ifndef ARCH_X86_64
677     add     esp, 0x60
678 %endif
679     RET
680
681 INIT_MMX
682 %ifdef ARCH_X86_64
683 ;-----------------------------------------------------------------------------
684 ; void x264_deblock_h_luma_intra_sse2( uint8_t *pix, int stride, int alpha, int beta )
685 ;-----------------------------------------------------------------------------
686 cglobal x264_deblock_h_luma_intra_%1, 4,7
687     movsxd r10, r1d
688     lea    r11, [r10*3]
689     lea    r6,  [r0-4]
690     lea    r5,  [r0-4+r11]
691     sub    rsp, 0x88
692     %define pix_tmp rsp
693
694     ; transpose 8x16 -> tmp space
695     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
696     lea    r6, [r6+r10*8]
697     lea    r5, [r5+r10*8]
698     TRANSPOSE8x8_MEM  PASS8ROWS(r6, r5, r10, r11), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
699
700     lea    r0,  [pix_tmp+0x40]
701     mov    r1,  0x10
702     call   x264_deblock_v_luma_intra_%1
703
704     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
705     lea    r5, [r6+r11]
706     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
707     shl    r10, 3
708     sub    r6,  r10
709     sub    r5,  r10
710     shr    r10, 3
711     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r6, r5, r10, r11)
712     add    rsp, 0x88
713     RET
714 %else
715 cglobal x264_deblock_h_luma_intra_%1, 2,4
716     lea    r3,  [r1*3]
717     sub    r0,  4
718     lea    r2,  [r0+r3]
719 %assign pad 0x8c-(stack_offset&15)
720     SUB    rsp, pad
721     %define pix_tmp rsp
722
723     ; transpose 8x16 -> tmp space
724     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30)
725     lea    r0,  [r0+r1*8]
726     lea    r2,  [r2+r1*8]
727     TRANSPOSE8x8_MEM  PASS8ROWS(r0, r2, r1, r3), PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30)
728
729     lea    r0,  [pix_tmp+0x40]
730     PUSH   dword r3m
731     PUSH   dword r2m
732     PUSH   dword 16
733     PUSH   r0
734     call   x264_deblock_%2_luma_intra_%1
735 %ifidn %2, v8
736     add    dword [rsp], 8 ; pix_tmp+8
737     call   x264_deblock_%2_luma_intra_%1
738 %endif
739     ADD    esp, 16
740
741     mov    r1,  r1m
742     mov    r0,  r0mp
743     lea    r3,  [r1*3]
744     sub    r0,  4
745     lea    r2,  [r0+r3]
746     ; transpose 16x6 -> original space (but we can't write only 6 pixels, so really 16x8)
747     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp, pix_tmp+0x30, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
748     lea    r0,  [r0+r1*8]
749     lea    r2,  [r2+r1*8]
750     TRANSPOSE8x8_MEM  PASS8ROWS(pix_tmp+8, pix_tmp+0x38, 0x10, 0x30), PASS8ROWS(r0, r2, r1, r3)
751     ADD    rsp, pad
752     RET
753 %endif ; ARCH_X86_64
754 %endmacro ; DEBLOCK_LUMA_INTRA
755
756 INIT_XMM
757 DEBLOCK_LUMA_INTRA sse2, v
758 %ifndef ARCH_X86_64
759 INIT_MMX
760 DEBLOCK_LUMA_INTRA mmxext, v8
761 %endif
762
763
764
765 INIT_MMX
766
767 %macro CHROMA_V_START 0
768     dec    r2d      ; alpha-1
769     dec    r3d      ; beta-1
770     mov    t5, r0
771     sub    t5, r1
772     sub    t5, r1
773 %endmacro
774
775 %macro CHROMA_H_START 0
776     dec    r2d
777     dec    r3d
778     sub    r0, 2
779     lea    t6, [r1*3]
780     mov    t5, r0
781     add    r0, t6
782 %endmacro
783
784 %define t5 r5
785 %define t6 r6
786
787 ;-----------------------------------------------------------------------------
788 ; void x264_deblock_v_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
789 ;-----------------------------------------------------------------------------
790 cglobal x264_deblock_v_chroma_mmxext, 5,6
791     CHROMA_V_START
792     movq  m0, [t5]
793     movq  m1, [t5+r1]
794     movq  m2, [r0]
795     movq  m3, [r0+r1]
796     call chroma_inter_body_mmxext
797     movq  [t5+r1], m1
798     movq  [r0], m2
799     RET
800
801 ;-----------------------------------------------------------------------------
802 ; void x264_deblock_h_chroma_mmxext( uint8_t *pix, int stride, int alpha, int beta, int8_t *tc0 )
803 ;-----------------------------------------------------------------------------
804 cglobal x264_deblock_h_chroma_mmxext, 5,7
805 %ifdef ARCH_X86_64
806     %define buf0 [rsp-24]
807     %define buf1 [rsp-16]
808 %else
809     %define buf0 r0m
810     %define buf1 r2m
811 %endif
812     CHROMA_H_START
813     TRANSPOSE4x8_LOAD  PASS8ROWS(t5, r0, r1, t6)
814     movq  buf0, m0
815     movq  buf1, m3
816     call chroma_inter_body_mmxext
817     movq  m0, buf0
818     movq  m3, buf1
819     TRANSPOSE8x4_STORE PASS8ROWS(t5, r0, r1, t6)
820     RET
821
822 ALIGN 16
823 chroma_inter_body_mmxext:
824     LOAD_MASK  r2d, r3d
825     movd       m6, [r4] ; tc0
826     punpcklbw  m6, m6
827     pand       m7, m6
828     DEBLOCK_P0_Q0
829     ret
830
831
832
833 ; in: %1=p0 %2=p1 %3=q1
834 ; out: p0 = (p0 + q1 + 2*p1 + 2) >> 2
835 %macro CHROMA_INTRA_P0 3
836     movq    m4, %1
837     pxor    m4, %3
838     pand    m4, [pb_01 GLOBAL] ; m4 = (p0^q1)&1
839     pavgb   %1, %3
840     psubusb %1, m4
841     pavgb   %1, %2             ; dst = avg(p1, avg(p0,q1) - ((p0^q1)&1))
842 %endmacro
843
844 %define t5 r4
845 %define t6 r5
846
847 ;-----------------------------------------------------------------------------
848 ; void x264_deblock_v_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
849 ;-----------------------------------------------------------------------------
850 cglobal x264_deblock_v_chroma_intra_mmxext, 4,5
851     CHROMA_V_START
852     movq  m0, [t5]
853     movq  m1, [t5+r1]
854     movq  m2, [r0]
855     movq  m3, [r0+r1]
856     call chroma_intra_body_mmxext
857     movq  [t5+r1], m1
858     movq  [r0], m2
859     RET
860
861 ;-----------------------------------------------------------------------------
862 ; void x264_deblock_h_chroma_intra_mmxext( uint8_t *pix, int stride, int alpha, int beta )
863 ;-----------------------------------------------------------------------------
864 cglobal x264_deblock_h_chroma_intra_mmxext, 4,6
865     CHROMA_H_START
866     TRANSPOSE4x8_LOAD  PASS8ROWS(t5, r0, r1, t6)
867     call chroma_intra_body_mmxext
868     TRANSPOSE8x4_STORE PASS8ROWS(t5, r0, r1, t6)
869     RET
870
871 ALIGN 16
872 chroma_intra_body_mmxext:
873     LOAD_MASK r2d, r3d
874     movq   m5, m1
875     movq   m6, m2
876     CHROMA_INTRA_P0  m1, m0, m3
877     CHROMA_INTRA_P0  m2, m3, m0
878     psubb  m1, m5
879     psubb  m2, m6
880     pand   m1, m7
881     pand   m2, m7
882     paddb  m1, m5
883     paddb  m2, m6
884     ret