x86: AVX2 high bit-depth pixel_sad
[x264/x264-sandbox.git] / common / x86 / sad16-a.asm
1 ;*****************************************************************************
2 ;* sad16-a.asm: x86 high depth sad functions
3 ;*****************************************************************************
4 ;* Copyright (C) 2010-2013 x264 project
5 ;*
6 ;* Authors: Oskar Arvidsson <oskar@irock.se>
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 ;* This program is also available under a commercial proprietary license.
23 ;* For more information, contact us at licensing@x264.com.
24 ;*****************************************************************************
25
26 %include "x86inc.asm"
27 %include "x86util.asm"
28
29 SECTION .text
30
31 cextern pw_1
32 cextern pw_4
33 cextern pw_8
34
35 ;=============================================================================
36 ; SAD MMX
37 ;=============================================================================
38
39 %macro SAD_INC_1x16P_MMX 0
40     movu    m1, [r0+ 0]
41     movu    m2, [r0+ 8]
42     movu    m3, [r0+16]
43     movu    m4, [r0+24]
44     psubw   m1, [r2+ 0]
45     psubw   m2, [r2+ 8]
46     psubw   m3, [r2+16]
47     psubw   m4, [r2+24]
48     ABSW2   m1, m2, m1, m2, m5, m6
49     ABSW2   m3, m4, m3, m4, m7, m5
50     lea     r0, [r0+2*r1]
51     lea     r2, [r2+2*r3]
52     paddw   m1, m2
53     paddw   m3, m4
54     paddw   m0, m1
55     paddw   m0, m3
56 %endmacro
57
58 %macro SAD_INC_2x8P_MMX 0
59     movu    m1, [r0+0]
60     movu    m2, [r0+8]
61     movu    m3, [r0+2*r1+0]
62     movu    m4, [r0+2*r1+8]
63     psubw   m1, [r2+0]
64     psubw   m2, [r2+8]
65     psubw   m3, [r2+2*r3+0]
66     psubw   m4, [r2+2*r3+8]
67     ABSW2   m1, m2, m1, m2, m5, m6
68     ABSW2   m3, m4, m3, m4, m7, m5
69     lea     r0, [r0+4*r1]
70     lea     r2, [r2+4*r3]
71     paddw   m1, m2
72     paddw   m3, m4
73     paddw   m0, m1
74     paddw   m0, m3
75 %endmacro
76
77 %macro SAD_INC_2x4P_MMX 0
78     movu    m1, [r0]
79     movu    m2, [r0+2*r1]
80     psubw   m1, [r2]
81     psubw   m2, [r2+2*r3]
82     ABSW2   m1, m2, m1, m2, m3, m4
83     lea     r0, [r0+4*r1]
84     lea     r2, [r2+4*r3]
85     paddw   m0, m1
86     paddw   m0, m2
87 %endmacro
88
89 ;-----------------------------------------------------------------------------
90 ; int pixel_sad_NxM( uint16_t *, intptr_t, uint16_t *, intptr_t )
91 ;-----------------------------------------------------------------------------
92 %macro SAD_MMX 3
93 cglobal pixel_sad_%1x%2, 4,5-(%2&4/4)
94     pxor    m0, m0
95 %if %2 == 4
96     SAD_INC_%3x%1P_MMX
97     SAD_INC_%3x%1P_MMX
98 %else
99     mov    r4d, %2/%3
100 .loop:
101     SAD_INC_%3x%1P_MMX
102     dec    r4d
103     jg .loop
104 %endif
105 %if %1*%2 == 256
106     HADDUW  m0, m1
107 %else
108     HADDW   m0, m1
109 %endif
110     movd   eax, m0
111     RET
112 %endmacro
113
114 INIT_MMX mmx2
115 SAD_MMX 16, 16, 1
116 SAD_MMX 16,  8, 1
117 SAD_MMX  8, 16, 2
118 SAD_MMX  8,  8, 2
119 SAD_MMX  8,  4, 2
120 SAD_MMX  4,  8, 2
121 SAD_MMX  4,  4, 2
122 INIT_MMX ssse3
123 SAD_MMX  4,  8, 2
124 SAD_MMX  4,  4, 2
125
126 ;=============================================================================
127 ; SAD XMM
128 ;=============================================================================
129
130 %macro SAD_INC_2ROW 1
131 %if 2*%1 > mmsize
132     movu    m1, [r2+ 0]
133     movu    m2, [r2+16]
134     movu    m3, [r2+2*r3+ 0]
135     movu    m4, [r2+2*r3+16]
136     psubw   m1, [r0+ 0]
137     psubw   m2, [r0+16]
138     psubw   m3, [r0+2*r1+ 0]
139     psubw   m4, [r0+2*r1+16]
140     ABSW2   m1, m2, m1, m2, m5, m6
141     lea     r0, [r0+4*r1]
142     lea     r2, [r2+4*r3]
143     ABSW2   m3, m4, m3, m4, m7, m5
144     paddw   m1, m2
145     paddw   m3, m4
146     paddw   m0, m1
147     paddw   m0, m3
148 %else
149     movu    m1, [r2]
150     movu    m2, [r2+2*r3]
151     psubw   m1, [r0]
152     psubw   m2, [r0+2*r1]
153     ABSW2   m1, m2, m1, m2, m3, m4
154     lea     r0, [r0+4*r1]
155     lea     r2, [r2+4*r3]
156     paddw   m0, m1
157     paddw   m0, m2
158 %endif
159 %endmacro
160
161 ;-----------------------------------------------------------------------------
162 ; int pixel_sad_NxM( uint16_t *, intptr_t, uint16_t *, intptr_t )
163 ;-----------------------------------------------------------------------------
164 %macro SAD 2
165 cglobal pixel_sad_%1x%2, 4,5-(%2&4/4),8*(%1/mmsize)
166     pxor    m0, m0
167 %if %2 == 4
168     SAD_INC_2ROW %1
169     SAD_INC_2ROW %1
170 %else
171     mov    r4d, %2/2
172 .loop:
173     SAD_INC_2ROW %1
174     dec    r4d
175     jg .loop
176 %endif
177     HADDW   m0, m1
178     movd   eax, xm0
179     RET
180 %endmacro
181
182 INIT_XMM sse2
183 SAD 16, 16
184 SAD 16,  8
185 SAD  8, 16
186 SAD  8,  8
187 SAD  8,  4
188 INIT_XMM sse2, aligned
189 SAD 16, 16
190 SAD 16,  8
191 SAD  8, 16
192 SAD  8,  8
193 INIT_XMM ssse3
194 SAD 16, 16
195 SAD 16,  8
196 SAD  8, 16
197 SAD  8,  8
198 SAD  8,  4
199 INIT_XMM ssse3, aligned
200 SAD 16, 16
201 SAD 16,  8
202 SAD  8, 16
203 SAD  8,  8
204 INIT_YMM avx2
205 SAD 16, 16
206 SAD 16,  8
207 INIT_YMM avx2, aligned
208 SAD 16, 16
209 SAD 16,  8
210
211 ;=============================================================================
212 ; SAD x3/x4
213 ;=============================================================================
214
215 %macro SAD_X3_INC_P 0
216     add     r0, 4*FENC_STRIDE
217     lea     r1, [r1+4*r4]
218     lea     r2, [r2+4*r4]
219     lea     r3, [r3+4*r4]
220 %endmacro
221
222 %macro SAD_X3_ONE_START 0
223     mova    m3, [r0]
224     movu    m0, [r1]
225     movu    m1, [r2]
226     movu    m2, [r3]
227     psubw   m0, m3
228     psubw   m1, m3
229     psubw   m2, m3
230     ABSW2   m0, m1, m0, m1, m4, m5
231     ABSW    m2, m2, m6
232 %endmacro
233
234 %macro SAD_X3_ONE 2
235     mova    m6, [r0+%1]
236     movu    m3, [r1+%2]
237     movu    m4, [r2+%2]
238     movu    m5, [r3+%2]
239     psubw   m3, m6
240     psubw   m4, m6
241     psubw   m5, m6
242     ABSW2   m3, m4, m3, m4, m7, m6
243     ABSW    m5, m5, m6
244     paddw   m0, m3
245     paddw   m1, m4
246     paddw   m2, m5
247 %endmacro
248
249 %macro SAD_X3_END 2
250 %if mmsize == 8 && %1*%2 == 256
251     HADDUW   m0, m3
252     HADDUW   m1, m4
253     HADDUW   m2, m5
254 %else
255     HADDW    m0, m3
256     HADDW    m1, m4
257     HADDW    m2, m5
258 %endif
259 %if UNIX64
260     movd [r5+0], m0
261     movd [r5+4], m1
262     movd [r5+8], m2
263 %else
264     mov      r0, r5mp
265     movd [r0+0], m0
266     movd [r0+4], m1
267     movd [r0+8], m2
268 %endif
269     RET
270 %endmacro
271
272 %macro SAD_X4_INC_P 0
273     add     r0, 4*FENC_STRIDE
274     lea     r1, [r1+4*r5]
275     lea     r2, [r2+4*r5]
276     lea     r3, [r3+4*r5]
277     lea     r4, [r4+4*r5]
278 %endmacro
279
280 %macro SAD_X4_ONE_START 0
281     mova    m4, [r0]
282     movu    m0, [r1]
283     movu    m1, [r2]
284     movu    m2, [r3]
285     movu    m3, [r4]
286     psubw   m0, m4
287     psubw   m1, m4
288     psubw   m2, m4
289     psubw   m3, m4
290     ABSW2   m0, m1, m0, m1, m5, m6
291     ABSW2   m2, m3, m2, m3, m4, m7
292 %endmacro
293
294 %macro SAD_X4_ONE 2
295     mova    m4, [r0+%1]
296     movu    m5, [r1+%2]
297     movu    m6, [r2+%2]
298 %if num_mmregs > 8
299     movu    m7, [r3+%2]
300     movu    m8, [r4+%2]
301     psubw   m5, m4
302     psubw   m6, m4
303     psubw   m7, m4
304     psubw   m8, m4
305     ABSW2   m5, m6, m5, m6, m9, m10
306     ABSW2   m7, m8, m7, m8, m9, m10
307     paddw   m0, m5
308     paddw   m1, m6
309     paddw   m2, m7
310     paddw   m3, m8
311 %elif cpuflag(ssse3)
312     movu    m7, [r3+%2]
313     psubw   m5, m4
314     psubw   m6, m4
315     psubw   m7, m4
316     movu    m4, [r4+%2]
317     pabsw   m5, m5
318     psubw   m4, [r0+%1]
319     pabsw   m6, m6
320     pabsw   m7, m7
321     pabsw   m4, m4
322     paddw   m0, m5
323     paddw   m1, m6
324     paddw   m2, m7
325     paddw   m3, m4
326 %else ; num_mmregs == 8 && !ssse3
327     psubw   m5, m4
328     psubw   m6, m4
329     ABSW    m5, m5, m7
330     ABSW    m6, m6, m7
331     paddw   m0, m5
332     paddw   m1, m6
333     movu    m5, [r3+%2]
334     movu    m6, [r4+%2]
335     psubw   m5, m4
336     psubw   m6, m4
337     ABSW2   m5, m6, m5, m6, m7, m4
338     paddw   m2, m5
339     paddw   m3, m6
340 %endif
341 %endmacro
342
343 %macro SAD_X4_END 2
344 %if mmsize == 8 && %1*%2 == 256
345     HADDUW    m0, m4
346     HADDUW    m1, m5
347     HADDUW    m2, m6
348     HADDUW    m3, m7
349 %else
350     HADDW     m0, m4
351     HADDW     m1, m5
352     HADDW     m2, m6
353     HADDW     m3, m7
354 %endif
355     mov       r0, r6mp
356     movd [r0+ 0], m0
357     movd [r0+ 4], m1
358     movd [r0+ 8], m2
359     movd [r0+12], m3
360     RET
361 %endmacro
362
363 %macro SAD_X_2xNP 4
364     %assign x %3
365 %rep %4
366     SAD_X%1_ONE x*mmsize, x*mmsize
367     SAD_X%1_ONE 2*FENC_STRIDE+x*mmsize, 2*%2+x*mmsize
368     %assign x x+1
369 %endrep
370 %endmacro
371
372 %macro PIXEL_VSAD 0
373 cglobal pixel_vsad, 3,3,8
374     mova      m0, [r0]
375     mova      m1, [r0+16]
376     mova      m2, [r0+2*r1]
377     mova      m3, [r0+2*r1+16]
378     lea       r0, [r0+4*r1]
379     psubw     m0, m2
380     psubw     m1, m3
381     ABSW2     m0, m1, m0, m1, m4, m5
382     paddw     m0, m1
383     sub      r2d, 2
384     je .end
385 .loop:
386     mova      m4, [r0]
387     mova      m5, [r0+16]
388     mova      m6, [r0+2*r1]
389     mova      m7, [r0+2*r1+16]
390     lea       r0, [r0+4*r1]
391     psubw     m2, m4
392     psubw     m3, m5
393     psubw     m4, m6
394     psubw     m5, m7
395     ABSW      m2, m2, m1
396     ABSW      m3, m3, m1
397     ABSW      m4, m4, m1
398     ABSW      m5, m5, m1
399     paddw     m0, m2
400     paddw     m0, m3
401     paddw     m0, m4
402     paddw     m0, m5
403     mova      m2, m6
404     mova      m3, m7
405     sub r2d, 2
406     jg .loop
407 .end:
408 %if BIT_DEPTH == 9
409     HADDW     m0, m1 ; max sum: 62(pixel diffs)*511(pixel_max)=31682
410 %else
411     HADDUW    m0, m1 ; max sum: 62(pixel diffs)*1023(pixel_max)=63426
412 %endif
413     movd     eax, m0
414     RET
415 %endmacro
416 INIT_XMM sse2
417 PIXEL_VSAD
418 INIT_XMM ssse3
419 PIXEL_VSAD
420 INIT_XMM xop
421 PIXEL_VSAD
422
423 ;-----------------------------------------------------------------------------
424 ; void pixel_sad_xK_MxN( uint16_t *fenc, uint16_t *pix0, uint16_t *pix1,
425 ;                        uint16_t *pix2, intptr_t i_stride, int scores[3] )
426 ;-----------------------------------------------------------------------------
427 %macro SAD_X 3
428 cglobal pixel_sad_x%1_%2x%3, 6,7,XMM_REGS
429     %assign regnum %1+1
430     %xdefine STRIDE r %+ regnum
431     mov     r6, %3/2-1
432     SAD_X%1_ONE_START
433     SAD_X%1_ONE 2*FENC_STRIDE, 2*STRIDE
434     SAD_X_2xNP %1, STRIDE, 1, %2/(mmsize/2)-1
435 .loop:
436     SAD_X%1_INC_P
437     SAD_X_2xNP %1, STRIDE, 0, %2/(mmsize/2)
438     dec     r6
439     jg .loop
440 %if %1 == 4
441     mov     r6, r6m
442 %endif
443     SAD_X%1_END %2, %3
444 %endmacro
445
446 INIT_MMX mmx2
447 %define XMM_REGS 0
448 SAD_X 3, 16, 16
449 SAD_X 3, 16,  8
450 SAD_X 3,  8, 16
451 SAD_X 3,  8,  8
452 SAD_X 3,  8,  4
453 SAD_X 3,  4,  8
454 SAD_X 3,  4,  4
455 SAD_X 4, 16, 16
456 SAD_X 4, 16,  8
457 SAD_X 4,  8, 16
458 SAD_X 4,  8,  8
459 SAD_X 4,  8,  4
460 SAD_X 4,  4,  8
461 SAD_X 4,  4,  4
462 INIT_MMX ssse3
463 SAD_X 3,  4,  8
464 SAD_X 3,  4,  4
465 SAD_X 4,  4,  8
466 SAD_X 4,  4,  4
467 INIT_XMM ssse3
468 %define XMM_REGS 9
469 SAD_X 3, 16, 16
470 SAD_X 3, 16,  8
471 SAD_X 3,  8, 16
472 SAD_X 3,  8,  8
473 SAD_X 3,  8,  4
474 SAD_X 4, 16, 16
475 SAD_X 4, 16,  8
476 SAD_X 4,  8, 16
477 SAD_X 4,  8,  8
478 SAD_X 4,  8,  4
479 INIT_XMM sse2
480 %define XMM_REGS 11
481 SAD_X 3, 16, 16
482 SAD_X 3, 16,  8
483 SAD_X 3,  8, 16
484 SAD_X 3,  8,  8
485 SAD_X 3,  8,  4
486 SAD_X 4, 16, 16
487 SAD_X 4, 16,  8
488 SAD_X 4,  8, 16
489 SAD_X 4,  8,  8
490 SAD_X 4,  8,  4
491
492 ;-----------------------------------------------------------------------------
493 ; void intra_sad_x3_4x4( uint16_t *fenc, uint16_t *fdec, int res[3] );
494 ;-----------------------------------------------------------------------------
495
496 %macro INTRA_SAD_X3_4x4 0
497 cglobal intra_sad_x3_4x4, 3,3,7
498     movq      m0, [r1-1*FDEC_STRIDEB]
499     movq      m1, [r0+0*FENC_STRIDEB]
500     movq      m2, [r0+2*FENC_STRIDEB]
501     pshuflw   m6, m0, q1032
502     paddw     m6, m0
503     pshuflw   m5, m6, q2301
504     paddw     m6, m5
505     punpcklqdq m6, m6       ;A+B+C+D 8 times
506     punpcklqdq m0, m0
507     movhps    m1, [r0+1*FENC_STRIDEB]
508     movhps    m2, [r0+3*FENC_STRIDEB]
509     psubw     m3, m1, m0
510     psubw     m0, m2
511     ABSW      m3, m3, m5
512     ABSW      m0, m0, m5
513     paddw     m0, m3
514     HADDW     m0, m5
515     movd    [r2], m0 ;V prediction cost
516     movd      m3, [r1+0*FDEC_STRIDEB-4]
517     movhps    m3, [r1+1*FDEC_STRIDEB-8]
518     movd      m4, [r1+2*FDEC_STRIDEB-4]
519     movhps    m4, [r1+3*FDEC_STRIDEB-8]
520     pshufhw   m3, m3, q3333
521     pshufhw   m4, m4, q3333
522     pshuflw   m3, m3, q1111 ; FF FF EE EE
523     pshuflw   m4, m4, q1111 ; HH HH GG GG
524     paddw     m5, m3, m4
525     pshufd    m0, m5, q1032
526     paddw     m5, m6
527     paddw     m5, m0
528     paddw     m5, [pw_4]
529     psrlw     m5, 3
530     psubw     m6, m5, m2
531     psubw     m5, m1
532     psubw     m1, m3
533     psubw     m2, m4
534     ABSW      m5, m5, m0
535     ABSW      m6, m6, m0
536     ABSW      m1, m1, m0
537     ABSW      m2, m2, m0
538     paddw     m5, m6
539     paddw     m1, m2
540     HADDW     m5, m0
541     HADDW     m1, m2
542     movd  [r2+8], m5        ;DC prediction cost
543     movd  [r2+4], m1        ;H prediction cost
544     RET
545 %endmacro
546
547 INIT_XMM sse2
548 INTRA_SAD_X3_4x4
549 INIT_XMM ssse3
550 INTRA_SAD_X3_4x4
551 INIT_XMM avx
552 INTRA_SAD_X3_4x4
553
554 ;-----------------------------------------------------------------------------
555 ; void intra_sad_x3_8x8( pixel *fenc, pixel edge[36], int res[3] );
556 ;-----------------------------------------------------------------------------
557
558 ;m0 = DC
559 ;m6 = V
560 ;m7 = H
561 ;m1 = DC score
562 ;m2 = V score
563 ;m3 = H score
564 ;m5 = temp
565 ;m4 = pixel row
566
567 %macro INTRA_SAD_HVDC_ITER 2
568     mova        m4, [r0+(%1-4)*FENC_STRIDEB]
569     psubw       m4, m0
570     ABSW        m4, m4, m5
571     ACCUM    paddw, 1, 4, %1
572     mova        m4, [r0+(%1-4)*FENC_STRIDEB]
573     psubw       m4, m6
574     ABSW        m4, m4, m5
575     ACCUM    paddw, 2, 4, %1
576     pshufd      m5, m7, %2
577     psubw       m5, [r0+(%1-4)*FENC_STRIDEB]
578     ABSW        m5, m5, m4
579     ACCUM    paddw, 3, 5, %1
580 %endmacro
581
582 %macro INTRA_SAD_X3_8x8 0
583 cglobal intra_sad_x3_8x8, 3,3,8
584     add         r0, 4*FENC_STRIDEB
585     movu        m0, [r1+7*SIZEOF_PIXEL]
586     mova        m6, [r1+16*SIZEOF_PIXEL] ;V prediction
587     mova        m7, m0
588     paddw       m0, m6
589     punpckhwd   m7, m7
590     HADDW       m0, m4
591     paddw       m0, [pw_8]
592     psrlw       m0, 4
593     SPLATW      m0, m0
594     INTRA_SAD_HVDC_ITER 0, q3333
595     INTRA_SAD_HVDC_ITER 1, q2222
596     INTRA_SAD_HVDC_ITER 2, q1111
597     INTRA_SAD_HVDC_ITER 3, q0000
598     movq        m7, [r1+7*SIZEOF_PIXEL]
599     punpcklwd   m7, m7
600     INTRA_SAD_HVDC_ITER 4, q3333
601     INTRA_SAD_HVDC_ITER 5, q2222
602     INTRA_SAD_HVDC_ITER 6, q1111
603     INTRA_SAD_HVDC_ITER 7, q0000
604     HADDW       m2, m4
605     HADDW       m3, m4
606     HADDW       m1, m4
607     movd    [r2+0], m2
608     movd    [r2+4], m3
609     movd    [r2+8], m1
610     RET
611 %endmacro
612
613 INIT_XMM sse2
614 INTRA_SAD_X3_8x8
615 INIT_XMM ssse3
616 INTRA_SAD_X3_8x8