]> git.sesse.net Git - x264/blob - common/x86/pixel-a.asm
x86: XOP pixel_ssd_nv12_core
[x264] / common / x86 / pixel-a.asm
1 ;*****************************************************************************
2 ;* pixel.asm: x86 pixel metrics
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2014 x264 project
5 ;*
6 ;* Authors: Loren Merritt <lorenm@u.washington.edu>
7 ;*          Holger Lubitz <holger@lubitz.org>
8 ;*          Laurent Aimar <fenrir@via.ecp.fr>
9 ;*          Alex Izvorski <aizvorksi@gmail.com>
10 ;*          Fiona Glaser <fiona@x264.com>
11 ;*          Oskar Arvidsson <oskar@irock.se>
12 ;*
13 ;* This program is free software; you can redistribute it and/or modify
14 ;* it under the terms of the GNU General Public License as published by
15 ;* the Free Software Foundation; either version 2 of the License, or
16 ;* (at your option) any later version.
17 ;*
18 ;* This program is distributed in the hope that it will be useful,
19 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
20 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 ;* GNU General Public License for more details.
22 ;*
23 ;* You should have received a copy of the GNU General Public License
24 ;* along with this program; if not, write to the Free Software
25 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
26 ;*
27 ;* This program is also available under a commercial proprietary license.
28 ;* For more information, contact us at licensing@x264.com.
29 ;*****************************************************************************
30
31 %include "x86inc.asm"
32 %include "x86util.asm"
33
34 SECTION_RODATA 32
35 hmul_16p:  times 16 db 1
36            times 8 db 1, -1
37 hmul_8p:   times 8 db 1
38            times 4 db 1, -1
39            times 8 db 1
40            times 4 db 1, -1
41 mask_ff:   times 16 db 0xff
42            times 16 db 0
43 mask_ac4:  times 2 dw 0, -1, -1, -1, 0, -1, -1, -1
44 mask_ac4b: times 2 dw 0, -1, 0, -1, -1, -1, -1, -1
45 mask_ac8:  times 2 dw 0, -1, -1, -1, -1, -1, -1, -1
46 %if BIT_DEPTH == 10
47 ssim_c1:   times 4 dd 6697.7856    ; .01*.01*1023*1023*64
48 ssim_c2:   times 4 dd 3797644.4352 ; .03*.03*1023*1023*64*63
49 pf_64:     times 4 dd 64.0
50 pf_128:    times 4 dd 128.0
51 %elif BIT_DEPTH == 9
52 ssim_c1:   times 4 dd 1671         ; .01*.01*511*511*64
53 ssim_c2:   times 4 dd 947556       ; .03*.03*511*511*64*63
54 %else ; 8-bit
55 ssim_c1:   times 4 dd 416          ; .01*.01*255*255*64
56 ssim_c2:   times 4 dd 235963       ; .03*.03*255*255*64*63
57 %endif
58 hmul_4p:   times 2 db 1, 1, 1, 1, 1, -1, 1, -1
59 mask_10:   times 4 dw 0, -1
60 mask_1100: times 2 dd 0, -1
61 pb_pppm:   times 4 db 1,1,1,-1
62 deinterleave_shuf: db 0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15
63 intrax3_shuf: db 7,6,7,6,5,4,5,4,3,2,3,2,1,0,1,0
64
65 intrax9a_ddlr1: db  6, 7, 8, 9, 7, 8, 9,10, 4, 5, 6, 7, 3, 4, 5, 6
66 intrax9a_ddlr2: db  8, 9,10,11, 9,10,11,12, 2, 3, 4, 5, 1, 2, 3, 4
67 intrax9a_hdu1:  db 15, 4, 5, 6,14, 3,15, 4,14, 2,13, 1,13, 1,12, 0
68 intrax9a_hdu2:  db 13, 2,14, 3,12, 1,13, 2,12, 0,11,11,11,11,11,11
69 intrax9a_vrl1:  db 10,11,12,13, 3, 4, 5, 6,11,12,13,14, 5, 6, 7, 8
70 intrax9a_vrl2:  db  2,10,11,12, 1, 3, 4, 5,12,13,14,15, 6, 7, 8, 9
71 intrax9a_vh1:   db  6, 7, 8, 9, 6, 7, 8, 9, 4, 4, 4, 4, 3, 3, 3, 3
72 intrax9a_vh2:   db  6, 7, 8, 9, 6, 7, 8, 9, 2, 2, 2, 2, 1, 1, 1, 1
73 intrax9a_dc:    db  1, 2, 3, 4, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,-1,-1
74 intrax9a_lut:   db 0x60,0x68,0x80,0x00,0x08,0x20,0x40,0x28,0x48,0,0,0,0,0,0,0
75 pw_s01234567:   dw 0x8000,0x8001,0x8002,0x8003,0x8004,0x8005,0x8006,0x8007
76 pw_s01234657:   dw 0x8000,0x8001,0x8002,0x8003,0x8004,0x8006,0x8005,0x8007
77 intrax9_edge:   db  0, 0, 1, 2, 3, 7, 8, 9,10,11,12,13,14,15,15,15
78
79 intrax9b_ddlr1: db  6, 7, 8, 9, 4, 5, 6, 7, 7, 8, 9,10, 3, 4, 5, 6
80 intrax9b_ddlr2: db  8, 9,10,11, 2, 3, 4, 5, 9,10,11,12, 1, 2, 3, 4
81 intrax9b_hdu1:  db 15, 4, 5, 6,14, 2,13, 1,14, 3,15, 4,13, 1,12, 0
82 intrax9b_hdu2:  db 13, 2,14, 3,12, 0,11,11,12, 1,13, 2,11,11,11,11
83 intrax9b_vrl1:  db 10,11,12,13,11,12,13,14, 3, 4, 5, 6, 5, 6, 7, 8
84 intrax9b_vrl2:  db  2,10,11,12,12,13,14,15, 1, 3, 4, 5, 6, 7, 8, 9
85 intrax9b_vh1:   db  6, 7, 8, 9, 4, 4, 4, 4, 6, 7, 8, 9, 3, 3, 3, 3
86 intrax9b_vh2:   db  6, 7, 8, 9, 2, 2, 2, 2, 6, 7, 8, 9, 1, 1, 1, 1
87 intrax9b_edge2: db  6, 7, 8, 9, 6, 7, 8, 9, 4, 3, 2, 1, 4, 3, 2, 1
88 intrax9b_v1:    db  0, 1,-1,-1,-1,-1,-1,-1, 4, 5,-1,-1,-1,-1,-1,-1
89 intrax9b_v2:    db  2, 3,-1,-1,-1,-1,-1,-1, 6, 7,-1,-1,-1,-1,-1,-1
90 intrax9b_lut:   db 0x60,0x64,0x80,0x00,0x04,0x20,0x40,0x24,0x44,0,0,0,0,0,0,0
91
92 ALIGN 32
93 intra8x9_h1:   db  7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5
94 intra8x9_h2:   db  6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4
95 intra8x9_h3:   db  3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1
96 intra8x9_h4:   db  2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0
97 intra8x9_ddl1: db  1, 2, 3, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7, 8, 9,10
98 intra8x9_ddl2: db  2, 3, 4, 5, 6, 7, 8, 9, 4, 5, 6, 7, 8, 9,10,11
99 intra8x9_ddl3: db  5, 6, 7, 8, 9,10,11,12, 7, 8, 9,10,11,12,13,14
100 intra8x9_ddl4: db  6, 7, 8, 9,10,11,12,13, 8, 9,10,11,12,13,14,15
101 intra8x9_vl1:  db  0, 1, 2, 3, 4, 5, 6, 7, 1, 2, 3, 4, 5, 6, 7, 8
102 intra8x9_vl2:  db  1, 2, 3, 4, 5, 6, 7, 8, 2, 3, 4, 5, 6, 7, 8, 9
103 intra8x9_vl3:  db  2, 3, 4, 5, 6, 7, 8, 9, 3, 4, 5, 6, 7, 8, 9,10
104 intra8x9_vl4:  db  3, 4, 5, 6, 7, 8, 9,10, 4, 5, 6, 7, 8, 9,10,11
105 intra8x9_ddr1: db  8, 9,10,11,12,13,14,15, 6, 7, 8, 9,10,11,12,13
106 intra8x9_ddr2: db  7, 8, 9,10,11,12,13,14, 5, 6, 7, 8, 9,10,11,12
107 intra8x9_ddr3: db  4, 5, 6, 7, 8, 9,10,11, 2, 3, 4, 5, 6, 7, 8, 9
108 intra8x9_ddr4: db  3, 4, 5, 6, 7, 8, 9,10, 1, 2, 3, 4, 5, 6, 7, 8
109 intra8x9_vr1:  db  8, 9,10,11,12,13,14,15, 7, 8, 9,10,11,12,13,14
110 intra8x9_vr2:  db  8, 9,10,11,12,13,14,15, 6, 8, 9,10,11,12,13,14
111 intra8x9_vr3:  db  5, 7, 8, 9,10,11,12,13, 3, 5, 7, 8, 9,10,11,12
112 intra8x9_vr4:  db  4, 6, 8, 9,10,11,12,13, 2, 4, 6, 8, 9,10,11,12
113 intra8x9_hd1:  db  3, 8, 9,10,11,12,13,14, 1, 6, 2, 7, 3, 8, 9,10
114 intra8x9_hd2:  db  2, 7, 3, 8, 9,10,11,12, 0, 5, 1, 6, 2, 7, 3, 8
115 intra8x9_hd3:  db  7, 8, 9,10,11,12,13,14, 3, 4, 5, 6, 7, 8, 9,10
116 intra8x9_hd4:  db  5, 6, 7, 8, 9,10,11,12, 1, 2, 3, 4, 5, 6, 7, 8
117 intra8x9_hu1:  db 13,12,11,10, 9, 8, 7, 6, 9, 8, 7, 6, 5, 4, 3, 2
118 intra8x9_hu2:  db 11,10, 9, 8, 7, 6, 5, 4, 7, 6, 5, 4, 3, 2, 1, 0
119 intra8x9_hu3:  db  5, 4, 3, 2, 1, 0,15,15, 1, 0,15,15,15,15,15,15
120 intra8x9_hu4:  db  3, 2, 1, 0,15,15,15,15,15,15,15,15,15,15,15,15
121 pw_s00112233:  dw 0x8000,0x8000,0x8001,0x8001,0x8002,0x8002,0x8003,0x8003
122 pw_s00001111:  dw 0x8000,0x8000,0x8000,0x8000,0x8001,0x8001,0x8001,0x8001
123
124 transd_shuf1: SHUFFLE_MASK_W 0, 8, 2, 10, 4, 12, 6, 14
125 transd_shuf2: SHUFFLE_MASK_W 1, 9, 3, 11, 5, 13, 7, 15
126
127 sw_f0:     dq 0xfff0, 0
128 pd_f0:     times 4 dd 0xffff0000
129
130 pw_76543210: dw 0, 1, 2, 3, 4, 5, 6, 7
131
132 ads_mvs_shuffle:
133 %macro ADS_MVS_SHUFFLE 8
134     %assign y x
135     %rep 8
136         %rep 7
137             %rotate (~y)&1
138             %assign y y>>((~y)&1)
139         %endrep
140         db %1*2, %1*2+1
141         %rotate 1
142         %assign y y>>1
143     %endrep
144 %endmacro
145 %assign x 0
146 %rep 256
147     ADS_MVS_SHUFFLE 0, 1, 2, 3, 4, 5, 6, 7
148 %assign x x+1
149 %endrep
150
151 SECTION .text
152
153 cextern pb_0
154 cextern pb_1
155 cextern pw_1
156 cextern pw_8
157 cextern pw_16
158 cextern pw_32
159 cextern pw_00ff
160 cextern pw_ppppmmmm
161 cextern pw_ppmmppmm
162 cextern pw_pmpmpmpm
163 cextern pw_pmmpzzzz
164 cextern pd_1
165 cextern hsub_mul
166 cextern popcnt_table
167
168 ;=============================================================================
169 ; SSD
170 ;=============================================================================
171
172 %if HIGH_BIT_DEPTH
173 ;-----------------------------------------------------------------------------
174 ; int pixel_ssd_WxH( uint16_t *, intptr_t, uint16_t *, intptr_t )
175 ;-----------------------------------------------------------------------------
176 %macro SSD_ONE 2
177 cglobal pixel_ssd_%1x%2, 4,7,6
178     FIX_STRIDES r1, r3
179 %if mmsize == %1*2
180     %define offset0_1 r1
181     %define offset0_2 r1*2
182     %define offset0_3 r5
183     %define offset1_1 r3
184     %define offset1_2 r3*2
185     %define offset1_3 r6
186     lea     r5, [3*r1]
187     lea     r6, [3*r3]
188 %elif mmsize == %1
189     %define offset0_1 mmsize
190     %define offset0_2 r1
191     %define offset0_3 r1+mmsize
192     %define offset1_1 mmsize
193     %define offset1_2 r3
194     %define offset1_3 r3+mmsize
195 %elif mmsize == %1/2
196     %define offset0_1 mmsize
197     %define offset0_2 mmsize*2
198     %define offset0_3 mmsize*3
199     %define offset1_1 mmsize
200     %define offset1_2 mmsize*2
201     %define offset1_3 mmsize*3
202 %endif
203     %assign %%n %2/(2*mmsize/%1)
204 %if %%n > 1
205     mov    r4d, %%n
206 %endif
207     pxor    m0, m0
208 .loop:
209     mova    m1, [r0]
210     mova    m2, [r0+offset0_1]
211     mova    m3, [r0+offset0_2]
212     mova    m4, [r0+offset0_3]
213     psubw   m1, [r2]
214     psubw   m2, [r2+offset1_1]
215     psubw   m3, [r2+offset1_2]
216     psubw   m4, [r2+offset1_3]
217 %if %%n > 1
218     lea     r0, [r0+r1*(%2/%%n)]
219     lea     r2, [r2+r3*(%2/%%n)]
220 %endif
221     pmaddwd m1, m1
222     pmaddwd m2, m2
223     pmaddwd m3, m3
224     pmaddwd m4, m4
225     paddd   m1, m2
226     paddd   m3, m4
227     paddd   m0, m1
228     paddd   m0, m3
229 %if %%n > 1
230     dec    r4d
231     jg .loop
232 %endif
233     HADDD   m0, m5
234     movd   eax, xm0
235     RET
236 %endmacro
237
238 INIT_MMX mmx2
239 SSD_ONE     4,  4
240 SSD_ONE     4,  8
241 SSD_ONE     4, 16
242 SSD_ONE     8,  4
243 SSD_ONE     8,  8
244 SSD_ONE     8, 16
245 SSD_ONE    16,  8
246 SSD_ONE    16, 16
247 INIT_XMM sse2
248 SSD_ONE     8,  4
249 SSD_ONE     8,  8
250 SSD_ONE     8, 16
251 SSD_ONE    16,  8
252 SSD_ONE    16, 16
253 INIT_YMM avx2
254 SSD_ONE    16,  8
255 SSD_ONE    16, 16
256 %endif ; HIGH_BIT_DEPTH
257
258 %if HIGH_BIT_DEPTH == 0
259 %macro SSD_LOAD_FULL 5
260     mova      m1, [t0+%1]
261     mova      m2, [t2+%2]
262     mova      m3, [t0+%3]
263     mova      m4, [t2+%4]
264 %if %5==1
265     add       t0, t1
266     add       t2, t3
267 %elif %5==2
268     lea       t0, [t0+2*t1]
269     lea       t2, [t2+2*t3]
270 %endif
271 %endmacro
272
273 %macro LOAD 5
274     movh      m%1, %3
275     movh      m%2, %4
276 %if %5
277     lea       t0, [t0+2*t1]
278 %endif
279 %endmacro
280
281 %macro JOIN 7
282     movh      m%3, %5
283     movh      m%4, %6
284 %if %7
285     lea       t2, [t2+2*t3]
286 %endif
287     punpcklbw m%1, m7
288     punpcklbw m%3, m7
289     psubw     m%1, m%3
290     punpcklbw m%2, m7
291     punpcklbw m%4, m7
292     psubw     m%2, m%4
293 %endmacro
294
295 %macro JOIN_SSE2 7
296     movh      m%3, %5
297     movh      m%4, %6
298 %if %7
299     lea       t2, [t2+2*t3]
300 %endif
301     punpcklqdq m%1, m%2
302     punpcklqdq m%3, m%4
303     DEINTB %2, %1, %4, %3, 7
304     psubw m%2, m%4
305     psubw m%1, m%3
306 %endmacro
307
308 %macro JOIN_SSSE3 7
309     movh      m%3, %5
310     movh      m%4, %6
311 %if %7
312     lea       t2, [t2+2*t3]
313 %endif
314     punpcklbw m%1, m%3
315     punpcklbw m%2, m%4
316 %endmacro
317
318 %macro LOAD_AVX2 5
319     mova     xm%1, %3
320     vinserti128 m%1, m%1, %4, 1
321 %if %5
322     lea       t0, [t0+2*t1]
323 %endif
324 %endmacro
325
326 %macro JOIN_AVX2 7
327     mova     xm%2, %5
328     vinserti128 m%2, m%2, %6, 1
329 %if %7
330     lea       t2, [t2+2*t3]
331 %endif
332     SBUTTERFLY bw, %1, %2, %3
333 %endmacro
334
335 %macro SSD_LOAD_HALF 5
336     LOAD      1, 2, [t0+%1], [t0+%3], 1
337     JOIN      1, 2, 3, 4, [t2+%2], [t2+%4], 1
338     LOAD      3, 4, [t0+%1], [t0+%3], %5
339     JOIN      3, 4, 5, 6, [t2+%2], [t2+%4], %5
340 %endmacro
341
342 %macro SSD_CORE 7-8
343 %ifidn %8, FULL
344     mova      m%6, m%2
345     mova      m%7, m%4
346     psubusb   m%2, m%1
347     psubusb   m%4, m%3
348     psubusb   m%1, m%6
349     psubusb   m%3, m%7
350     por       m%1, m%2
351     por       m%3, m%4
352     punpcklbw m%2, m%1, m%5
353     punpckhbw m%1, m%5
354     punpcklbw m%4, m%3, m%5
355     punpckhbw m%3, m%5
356 %endif
357     pmaddwd   m%1, m%1
358     pmaddwd   m%2, m%2
359     pmaddwd   m%3, m%3
360     pmaddwd   m%4, m%4
361 %endmacro
362
363 %macro SSD_CORE_SSE2 7-8
364 %ifidn %8, FULL
365     DEINTB %6, %1, %7, %2, %5
366     psubw m%6, m%7
367     psubw m%1, m%2
368     SWAP %6, %2, %1
369     DEINTB %6, %3, %7, %4, %5
370     psubw m%6, m%7
371     psubw m%3, m%4
372     SWAP %6, %4, %3
373 %endif
374     pmaddwd   m%1, m%1
375     pmaddwd   m%2, m%2
376     pmaddwd   m%3, m%3
377     pmaddwd   m%4, m%4
378 %endmacro
379
380 %macro SSD_CORE_SSSE3 7-8
381 %ifidn %8, FULL
382     punpckhbw m%6, m%1, m%2
383     punpckhbw m%7, m%3, m%4
384     punpcklbw m%1, m%2
385     punpcklbw m%3, m%4
386     SWAP %6, %2, %3
387     SWAP %7, %4
388 %endif
389     pmaddubsw m%1, m%5
390     pmaddubsw m%2, m%5
391     pmaddubsw m%3, m%5
392     pmaddubsw m%4, m%5
393     pmaddwd   m%1, m%1
394     pmaddwd   m%2, m%2
395     pmaddwd   m%3, m%3
396     pmaddwd   m%4, m%4
397 %endmacro
398
399 %macro SSD_ITER 6
400     SSD_LOAD_%1 %2,%3,%4,%5,%6
401     SSD_CORE  1, 2, 3, 4, 7, 5, 6, %1
402     paddd     m1, m2
403     paddd     m3, m4
404     paddd     m0, m1
405     paddd     m0, m3
406 %endmacro
407
408 ;-----------------------------------------------------------------------------
409 ; int pixel_ssd_16x16( uint8_t *, intptr_t, uint8_t *, intptr_t )
410 ;-----------------------------------------------------------------------------
411 %macro SSD 2
412 %if %1 != %2
413     %assign function_align 8
414 %else
415     %assign function_align 16
416 %endif
417 cglobal pixel_ssd_%1x%2, 0,0,0
418     mov     al, %1*%2/mmsize/2
419
420 %if %1 != %2
421     jmp mangle(x264_pixel_ssd_%1x%1 %+ SUFFIX %+ .startloop)
422 %else
423
424 .startloop:
425 %if ARCH_X86_64
426     DECLARE_REG_TMP 0,1,2,3
427     PROLOGUE 0,0,8
428 %else
429     PROLOGUE 0,5
430     DECLARE_REG_TMP 1,2,3,4
431     mov t0, r0m
432     mov t1, r1m
433     mov t2, r2m
434     mov t3, r3m
435 %endif
436
437 %if cpuflag(ssse3)
438     mova    m7, [hsub_mul]
439 %elifidn cpuname, sse2
440     mova    m7, [pw_00ff]
441 %elif %1 >= mmsize
442     pxor    m7, m7
443 %endif
444     pxor    m0, m0
445
446 ALIGN 16
447 .loop:
448 %if %1 > mmsize
449     SSD_ITER FULL, 0, 0, mmsize, mmsize, 1
450 %elif %1 == mmsize
451     SSD_ITER FULL, 0, 0, t1, t3, 2
452 %else
453     SSD_ITER HALF, 0, 0, t1, t3, 2
454 %endif
455     dec     al
456     jg .loop
457 %if mmsize==32
458     vextracti128 xm1, m0, 1
459     paddd  xm0, xm1
460     HADDD  xm0, xm1
461     movd   eax, xm0
462 %else
463     HADDD   m0, m1
464     movd   eax, m0
465 %endif
466     RET
467 %endif
468 %endmacro
469
470 INIT_MMX mmx
471 SSD 16, 16
472 SSD 16,  8
473 SSD  8,  8
474 SSD  8, 16
475 SSD  4,  4
476 SSD  8,  4
477 SSD  4,  8
478 SSD  4, 16
479 INIT_XMM sse2slow
480 SSD 16, 16
481 SSD  8,  8
482 SSD 16,  8
483 SSD  8, 16
484 SSD  8,  4
485 INIT_XMM sse2
486 %define SSD_CORE SSD_CORE_SSE2
487 %define JOIN JOIN_SSE2
488 SSD 16, 16
489 SSD  8,  8
490 SSD 16,  8
491 SSD  8, 16
492 SSD  8,  4
493 INIT_XMM ssse3
494 %define SSD_CORE SSD_CORE_SSSE3
495 %define JOIN JOIN_SSSE3
496 SSD 16, 16
497 SSD  8,  8
498 SSD 16,  8
499 SSD  8, 16
500 SSD  8,  4
501 INIT_XMM avx
502 SSD 16, 16
503 SSD  8,  8
504 SSD 16,  8
505 SSD  8, 16
506 SSD  8,  4
507 INIT_MMX ssse3
508 SSD  4,  4
509 SSD  4,  8
510 SSD  4, 16
511 INIT_XMM xop
512 SSD 16, 16
513 SSD  8,  8
514 SSD 16,  8
515 SSD  8, 16
516 SSD  8,  4
517 %define LOAD LOAD_AVX2
518 %define JOIN JOIN_AVX2
519 INIT_YMM avx2
520 SSD 16, 16
521 SSD 16,  8
522 %assign function_align 16
523 %endif ; !HIGH_BIT_DEPTH
524
525 ;-----------------------------------------------------------------------------
526 ; void pixel_ssd_nv12_core( uint16_t *pixuv1, intptr_t stride1, uint16_t *pixuv2, intptr_t stride2,
527 ;                           int width, int height, uint64_t *ssd_u, uint64_t *ssd_v )
528 ;
529 ; The maximum width this function can handle without risk of overflow is given
530 ; in the following equation: (mmsize in bits)
531 ;
532 ;   2 * mmsize/32 * (2^32 - 1) / (2^BIT_DEPTH - 1)^2
533 ;
534 ; For 10-bit MMX this means width >= 16416 and for XMM >= 32832. At sane
535 ; distortion levels it will take much more than that though.
536 ;-----------------------------------------------------------------------------
537 %if HIGH_BIT_DEPTH
538 %macro SSD_NV12 0
539 cglobal pixel_ssd_nv12_core, 6,7,7
540     shl        r4d, 2
541     FIX_STRIDES r1, r3
542     add         r0, r4
543     add         r2, r4
544     xor         r6, r6
545     pxor        m4, m4
546     pxor        m5, m5
547     pxor        m6, m6
548 .loopy:
549     mov         r6, r4
550     neg         r6
551     pxor        m2, m2
552     pxor        m3, m3
553 .loopx:
554     mova        m0, [r0+r6]
555     mova        m1, [r0+r6+mmsize]
556     psubw       m0, [r2+r6]
557     psubw       m1, [r2+r6+mmsize]
558     PSHUFLW     m0, m0, q3120
559     PSHUFLW     m1, m1, q3120
560 %if mmsize >= 16
561     pshufhw     m0, m0, q3120
562     pshufhw     m1, m1, q3120
563 %endif
564 %if cpuflag(xop)
565     pmadcswd    m2, m0, m0, m2
566     pmadcswd    m3, m1, m1, m3
567 %else
568     pmaddwd     m0, m0
569     pmaddwd     m1, m1
570     paddd       m2, m0
571     paddd       m3, m1
572 %endif
573     add         r6, 2*mmsize
574     jl .loopx
575 %if mmsize == 32 ; avx2 may overread by 32 bytes, that has to be handled
576     jz .no_overread
577     psubd       m3, m1
578 .no_overread:
579 %endif
580 %if mmsize >= 16 ; using HADDD would remove the mmsize/32 part from the
581                  ; equation above, putting the width limit at 8208
582     punpckhdq   m0, m2, m6
583     punpckhdq   m1, m3, m6
584     punpckldq   m2, m6
585     punpckldq   m3, m6
586     paddq       m3, m2
587     paddq       m1, m0
588     paddq       m4, m3
589     paddq       m4, m1
590 %else ; unfortunately paddq is sse2
591       ; emulate 48 bit precision for mmx2 instead
592     mova        m0, m2
593     mova        m1, m3
594     punpcklwd   m2, m6
595     punpcklwd   m3, m6
596     punpckhwd   m0, m6
597     punpckhwd   m1, m6
598     paddd       m3, m2
599     paddd       m1, m0
600     paddd       m4, m3
601     paddd       m5, m1
602 %endif
603     add         r0, r1
604     add         r2, r3
605     dec        r5d
606     jg .loopy
607     mov         r3, r6m
608     mov         r4, r7m
609 %if mmsize == 32
610     vextracti128 xm0, m4, 1
611     paddq      xm4, xm0
612 %endif
613 %if mmsize >= 16
614     movq      [r3], xm4
615     movhps    [r4], xm4
616 %else ; fixup for mmx2
617     SBUTTERFLY dq, 4, 5, 0
618     mova        m0, m4
619     psrld       m4, 16
620     paddd       m5, m4
621     pslld       m0, 16
622     SBUTTERFLY dq, 0, 5, 4
623     psrlq       m0, 16
624     psrlq       m5, 16
625     movq      [r3], m0
626     movq      [r4], m5
627 %endif
628     RET
629 %endmacro ; SSD_NV12
630 %endif ; HIGH_BIT_DEPTH
631
632 %if HIGH_BIT_DEPTH == 0
633 ;-----------------------------------------------------------------------------
634 ; void pixel_ssd_nv12_core( uint8_t *pixuv1, intptr_t stride1, uint8_t *pixuv2, intptr_t stride2,
635 ;                           int width, int height, uint64_t *ssd_u, uint64_t *ssd_v )
636 ;
637 ; This implementation can potentially overflow on image widths >= 11008 (or
638 ; 6604 if interlaced), since it is called on blocks of height up to 12 (resp
639 ; 20). At sane distortion levels it will take much more than that though.
640 ;-----------------------------------------------------------------------------
641 %macro SSD_NV12 0
642 cglobal pixel_ssd_nv12_core, 6,7
643     add    r4d, r4d
644     add     r0, r4
645     add     r2, r4
646     pxor    m3, m3
647     pxor    m4, m4
648     mova    m5, [pw_00ff]
649 .loopy:
650     mov     r6, r4
651     neg     r6
652 .loopx:
653 %if mmsize == 32 ; only 16-byte alignment is guaranteed
654     movu    m2, [r0+r6]
655     movu    m1, [r2+r6]
656 %else
657     mova    m2, [r0+r6]
658     mova    m1, [r2+r6]
659 %endif
660     psubusb m0, m2, m1
661     psubusb m1, m2
662     por     m0, m1
663     psrlw   m2, m0, 8
664     pand    m0, m5
665 %if cpuflag(xop)
666     pmadcswd m4, m2, m2, m4
667     pmadcswd m3, m0, m0, m3
668 %else
669     pmaddwd m2, m2
670     pmaddwd m0, m0
671     paddd   m4, m2
672     paddd   m3, m0
673 %endif
674     add     r6, mmsize
675     jl .loopx
676 %if mmsize == 32 ; avx2 may overread by 16 bytes, that has to be handled
677     jz .no_overread
678     pcmpeqb xm1, xm1
679     pandn   m0, m1, m0 ; zero the lower half
680     pandn   m2, m1, m2
681     psubd   m3, m0
682     psubd   m4, m2
683 .no_overread:
684 %endif
685     add     r0, r1
686     add     r2, r3
687     dec    r5d
688     jg .loopy
689     mov     r3, r6m
690     mov     r4, r7m
691     HADDD   m3, m0
692     HADDD   m4, m0
693     pxor   xm0, xm0
694     punpckldq xm3, xm0
695     punpckldq xm4, xm0
696     movq  [r3], xm3
697     movq  [r4], xm4
698     RET
699 %endmacro ; SSD_NV12
700 %endif ; !HIGH_BIT_DEPTH
701
702 INIT_MMX mmx2
703 SSD_NV12
704 INIT_XMM sse2
705 SSD_NV12
706 INIT_XMM avx
707 SSD_NV12
708 INIT_XMM xop
709 SSD_NV12
710 INIT_YMM avx2
711 SSD_NV12
712
713 ;=============================================================================
714 ; variance
715 ;=============================================================================
716
717 %macro VAR_START 1
718     pxor  m5, m5    ; sum
719     pxor  m6, m6    ; sum squared
720 %if HIGH_BIT_DEPTH == 0
721 %if %1
722     mova  m7, [pw_00ff]
723 %elif mmsize < 32
724     pxor  m7, m7    ; zero
725 %endif
726 %endif ; !HIGH_BIT_DEPTH
727 %endmacro
728
729 %macro VAR_END 2
730 %if HIGH_BIT_DEPTH
731 %if mmsize == 8 && %1*%2 == 256
732     HADDUW  m5, m2
733 %else
734     HADDW   m5, m2
735 %endif
736 %else ; !HIGH_BIT_DEPTH
737     HADDW   m5, m2
738 %endif ; HIGH_BIT_DEPTH
739     HADDD   m6, m1
740 %if ARCH_X86_64
741     punpckldq m5, m6
742     movq   rax, m5
743 %else
744     movd   eax, m5
745     movd   edx, m6
746 %endif
747     RET
748 %endmacro
749
750 %macro VAR_CORE 0
751     paddw     m5, m0
752     paddw     m5, m3
753     paddw     m5, m1
754     paddw     m5, m4
755     pmaddwd   m0, m0
756     pmaddwd   m3, m3
757     pmaddwd   m1, m1
758     pmaddwd   m4, m4
759     paddd     m6, m0
760     paddd     m6, m3
761     paddd     m6, m1
762     paddd     m6, m4
763 %endmacro
764
765 %macro VAR_2ROW 2
766     mov      r2d, %2
767 .loop:
768 %if HIGH_BIT_DEPTH
769     mova      m0, [r0]
770     mova      m1, [r0+mmsize]
771     mova      m3, [r0+%1]
772     mova      m4, [r0+%1+mmsize]
773 %else ; !HIGH_BIT_DEPTH
774     mova      m0, [r0]
775     punpckhbw m1, m0, m7
776     mova      m3, [r0+%1]
777     mova      m4, m3
778     punpcklbw m0, m7
779 %endif ; HIGH_BIT_DEPTH
780 %ifidn %1, r1
781     lea       r0, [r0+%1*2]
782 %else
783     add       r0, r1
784 %endif
785 %if HIGH_BIT_DEPTH == 0
786     punpcklbw m3, m7
787     punpckhbw m4, m7
788 %endif ; !HIGH_BIT_DEPTH
789     VAR_CORE
790     dec r2d
791     jg .loop
792 %endmacro
793
794 ;-----------------------------------------------------------------------------
795 ; int pixel_var_wxh( uint8_t *, intptr_t )
796 ;-----------------------------------------------------------------------------
797 INIT_MMX mmx2
798 cglobal pixel_var_16x16, 2,3
799     FIX_STRIDES r1
800     VAR_START 0
801     VAR_2ROW 8*SIZEOF_PIXEL, 16
802     VAR_END 16, 16
803
804 cglobal pixel_var_8x16, 2,3
805     FIX_STRIDES r1
806     VAR_START 0
807     VAR_2ROW r1, 8
808     VAR_END 8, 16
809
810 cglobal pixel_var_8x8, 2,3
811     FIX_STRIDES r1
812     VAR_START 0
813     VAR_2ROW r1, 4
814     VAR_END 8, 8
815
816 %if HIGH_BIT_DEPTH
817 %macro VAR 0
818 cglobal pixel_var_16x16, 2,3,8
819     FIX_STRIDES r1
820     VAR_START 0
821     VAR_2ROW r1, 8
822     VAR_END 16, 16
823
824 cglobal pixel_var_8x8, 2,3,8
825     lea       r2, [r1*3]
826     VAR_START 0
827     mova      m0, [r0]
828     mova      m1, [r0+r1*2]
829     mova      m3, [r0+r1*4]
830     mova      m4, [r0+r2*2]
831     lea       r0, [r0+r1*8]
832     VAR_CORE
833     mova      m0, [r0]
834     mova      m1, [r0+r1*2]
835     mova      m3, [r0+r1*4]
836     mova      m4, [r0+r2*2]
837     VAR_CORE
838     VAR_END 8, 8
839 %endmacro ; VAR
840
841 INIT_XMM sse2
842 VAR
843 INIT_XMM avx
844 VAR
845 INIT_XMM xop
846 VAR
847 %endif ; HIGH_BIT_DEPTH
848
849 %if HIGH_BIT_DEPTH == 0
850 %macro VAR 0
851 cglobal pixel_var_16x16, 2,3,8
852     VAR_START 1
853     mov      r2d, 8
854 .loop:
855     mova      m0, [r0]
856     mova      m3, [r0+r1]
857     DEINTB    1, 0, 4, 3, 7
858     lea       r0, [r0+r1*2]
859     VAR_CORE
860     dec r2d
861     jg .loop
862     VAR_END 16, 16
863
864 cglobal pixel_var_8x8, 2,4,8
865     VAR_START 1
866     mov      r2d, 2
867     lea       r3, [r1*3]
868 .loop:
869     movh      m0, [r0]
870     movh      m3, [r0+r1]
871     movhps    m0, [r0+r1*2]
872     movhps    m3, [r0+r3]
873     DEINTB    1, 0, 4, 3, 7
874     lea       r0, [r0+r1*4]
875     VAR_CORE
876     dec r2d
877     jg .loop
878     VAR_END 8, 8
879
880 cglobal pixel_var_8x16, 2,4,8
881     VAR_START 1
882     mov      r2d, 4
883     lea       r3, [r1*3]
884 .loop:
885     movh      m0, [r0]
886     movh      m3, [r0+r1]
887     movhps    m0, [r0+r1*2]
888     movhps    m3, [r0+r3]
889     DEINTB    1, 0, 4, 3, 7
890     lea       r0, [r0+r1*4]
891     VAR_CORE
892     dec r2d
893     jg .loop
894     VAR_END 8, 16
895 %endmacro ; VAR
896
897 INIT_XMM sse2
898 VAR
899 INIT_XMM avx
900 VAR
901 INIT_XMM xop
902 VAR
903
904 INIT_YMM avx2
905 cglobal pixel_var_16x16, 2,4,7
906     VAR_START 0
907     mov      r2d, 4
908     lea       r3, [r1*3]
909 .loop:
910     pmovzxbw  m0, [r0]
911     pmovzxbw  m3, [r0+r1]
912     pmovzxbw  m1, [r0+r1*2]
913     pmovzxbw  m4, [r0+r3]
914     lea       r0, [r0+r1*4]
915     VAR_CORE
916     dec r2d
917     jg .loop
918     vextracti128 xm0, m5, 1
919     vextracti128 xm1, m6, 1
920     paddw  xm5, xm0
921     paddd  xm6, xm1
922     HADDW  xm5, xm2
923     HADDD  xm6, xm1
924 %if ARCH_X86_64
925     punpckldq xm5, xm6
926     movq   rax, xm5
927 %else
928     movd   eax, xm5
929     movd   edx, xm6
930 %endif
931     RET
932 %endif ; !HIGH_BIT_DEPTH
933
934 %macro VAR2_END 3
935     HADDW   %2, xm1
936     movd   r1d, %2
937     imul   r1d, r1d
938     HADDD   %3, xm1
939     shr    r1d, %1
940     movd   eax, %3
941     movd  [r4], %3
942     sub    eax, r1d  ; sqr - (sum * sum >> shift)
943     RET
944 %endmacro
945
946 ;-----------------------------------------------------------------------------
947 ; int pixel_var2_8x8( pixel *, intptr_t, pixel *, intptr_t, int * )
948 ;-----------------------------------------------------------------------------
949 %macro VAR2_8x8_MMX 2
950 cglobal pixel_var2_8x%1, 5,6
951     FIX_STRIDES r1, r3
952     VAR_START 0
953     mov      r5d, %1
954 .loop:
955 %if HIGH_BIT_DEPTH
956     mova      m0, [r0]
957     mova      m1, [r0+mmsize]
958     psubw     m0, [r2]
959     psubw     m1, [r2+mmsize]
960 %else ; !HIGH_BIT_DEPTH
961     movq      m0, [r0]
962     movq      m1, m0
963     movq      m2, [r2]
964     movq      m3, m2
965     punpcklbw m0, m7
966     punpckhbw m1, m7
967     punpcklbw m2, m7
968     punpckhbw m3, m7
969     psubw     m0, m2
970     psubw     m1, m3
971 %endif ; HIGH_BIT_DEPTH
972     paddw     m5, m0
973     paddw     m5, m1
974     pmaddwd   m0, m0
975     pmaddwd   m1, m1
976     paddd     m6, m0
977     paddd     m6, m1
978     add       r0, r1
979     add       r2, r3
980     dec       r5d
981     jg .loop
982     VAR2_END %2, m5, m6
983 %endmacro
984
985 %if ARCH_X86_64 == 0
986 INIT_MMX mmx2
987 VAR2_8x8_MMX  8, 6
988 VAR2_8x8_MMX 16, 7
989 %endif
990
991 %macro VAR2_8x8_SSE2 2
992 cglobal pixel_var2_8x%1, 5,6,8
993     VAR_START 1
994     mov      r5d, %1/2
995 .loop:
996 %if HIGH_BIT_DEPTH
997     mova      m0, [r0]
998     mova      m1, [r0+r1*2]
999     mova      m2, [r2]
1000     mova      m3, [r2+r3*2]
1001 %else ; !HIGH_BIT_DEPTH
1002     movq      m1, [r0]
1003     movhps    m1, [r0+r1]
1004     movq      m3, [r2]
1005     movhps    m3, [r2+r3]
1006     DEINTB    0, 1, 2, 3, 7
1007 %endif ; HIGH_BIT_DEPTH
1008     psubw     m0, m2
1009     psubw     m1, m3
1010     paddw     m5, m0
1011     paddw     m5, m1
1012     pmaddwd   m0, m0
1013     pmaddwd   m1, m1
1014     paddd     m6, m0
1015     paddd     m6, m1
1016     lea       r0, [r0+r1*2*SIZEOF_PIXEL]
1017     lea       r2, [r2+r3*2*SIZEOF_PIXEL]
1018     dec      r5d
1019     jg .loop
1020     VAR2_END %2, m5, m6
1021 %endmacro
1022
1023 INIT_XMM sse2
1024 VAR2_8x8_SSE2  8, 6
1025 VAR2_8x8_SSE2 16, 7
1026
1027 %if HIGH_BIT_DEPTH == 0
1028 %macro VAR2_8x8_SSSE3 2
1029 cglobal pixel_var2_8x%1, 5,6,8
1030     pxor      m5, m5    ; sum
1031     pxor      m6, m6    ; sum squared
1032     mova      m7, [hsub_mul]
1033     mov      r5d, %1/4
1034 .loop:
1035     movq      m0, [r0]
1036     movq      m2, [r2]
1037     movq      m1, [r0+r1]
1038     movq      m3, [r2+r3]
1039     lea       r0, [r0+r1*2]
1040     lea       r2, [r2+r3*2]
1041     punpcklbw m0, m2
1042     punpcklbw m1, m3
1043     movq      m2, [r0]
1044     movq      m3, [r2]
1045     punpcklbw m2, m3
1046     movq      m3, [r0+r1]
1047     movq      m4, [r2+r3]
1048     punpcklbw m3, m4
1049     pmaddubsw m0, m7
1050     pmaddubsw m1, m7
1051     pmaddubsw m2, m7
1052     pmaddubsw m3, m7
1053     paddw     m5, m0
1054     paddw     m5, m1
1055     paddw     m5, m2
1056     paddw     m5, m3
1057     pmaddwd   m0, m0
1058     pmaddwd   m1, m1
1059     pmaddwd   m2, m2
1060     pmaddwd   m3, m3
1061     paddd     m6, m0
1062     paddd     m6, m1
1063     paddd     m6, m2
1064     paddd     m6, m3
1065     lea       r0, [r0+r1*2]
1066     lea       r2, [r2+r3*2]
1067     dec      r5d
1068     jg .loop
1069     VAR2_END %2, m5, m6
1070 %endmacro
1071
1072 INIT_XMM ssse3
1073 VAR2_8x8_SSSE3  8, 6
1074 VAR2_8x8_SSSE3 16, 7
1075 INIT_XMM xop
1076 VAR2_8x8_SSSE3  8, 6
1077 VAR2_8x8_SSSE3 16, 7
1078
1079 %macro VAR2_8x8_AVX2 2
1080 cglobal pixel_var2_8x%1, 5,6,6
1081     pxor      m3, m3    ; sum
1082     pxor      m4, m4    ; sum squared
1083     mova      m5, [hsub_mul]
1084     mov      r5d, %1/4
1085 .loop:
1086     movq     xm0, [r0]
1087     movq     xm1, [r2]
1088     vinserti128 m0, m0, [r0+r1], 1
1089     vinserti128 m1, m1, [r2+r3], 1
1090     lea       r0, [r0+r1*2]
1091     lea       r2, [r2+r3*2]
1092     punpcklbw m0, m1
1093     movq     xm1, [r0]
1094     movq     xm2, [r2]
1095     vinserti128 m1, m1, [r0+r1], 1
1096     vinserti128 m2, m2, [r2+r3], 1
1097     lea       r0, [r0+r1*2]
1098     lea       r2, [r2+r3*2]
1099     punpcklbw m1, m2
1100     pmaddubsw m0, m5
1101     pmaddubsw m1, m5
1102     paddw     m3, m0
1103     paddw     m3, m1
1104     pmaddwd   m0, m0
1105     pmaddwd   m1, m1
1106     paddd     m4, m0
1107     paddd     m4, m1
1108     dec      r5d
1109     jg .loop
1110     vextracti128 xm0, m3, 1
1111     vextracti128 xm1, m4, 1
1112     paddw    xm3, xm0
1113     paddd    xm4, xm1
1114     VAR2_END %2, xm3, xm4
1115 %endmacro
1116
1117 INIT_YMM avx2
1118 VAR2_8x8_AVX2  8, 6
1119 VAR2_8x8_AVX2 16, 7
1120
1121 %endif ; !HIGH_BIT_DEPTH
1122
1123 ;=============================================================================
1124 ; SATD
1125 ;=============================================================================
1126
1127 %macro JDUP 2
1128 %if cpuflag(sse4)
1129     ; just use shufps on anything post conroe
1130     shufps %1, %2, 0
1131 %elif cpuflag(ssse3) && notcpuflag(atom)
1132     ; join 2x 32 bit and duplicate them
1133     ; emulating shufps is faster on conroe
1134     punpcklqdq %1, %2
1135     movsldup %1, %1
1136 %else
1137     ; doesn't need to dup. sse2 does things by zero extending to words and full h_2d
1138     punpckldq %1, %2
1139 %endif
1140 %endmacro
1141
1142 %macro HSUMSUB 5
1143     pmaddubsw m%2, m%5
1144     pmaddubsw m%1, m%5
1145     pmaddubsw m%4, m%5
1146     pmaddubsw m%3, m%5
1147 %endmacro
1148
1149 %macro DIFF_UNPACK_SSE2 5
1150     punpcklbw m%1, m%5
1151     punpcklbw m%2, m%5
1152     punpcklbw m%3, m%5
1153     punpcklbw m%4, m%5
1154     psubw m%1, m%2
1155     psubw m%3, m%4
1156 %endmacro
1157
1158 %macro DIFF_SUMSUB_SSSE3 5
1159     HSUMSUB %1, %2, %3, %4, %5
1160     psubw m%1, m%2
1161     psubw m%3, m%4
1162 %endmacro
1163
1164 %macro LOAD_DUP_2x4P 4 ; dst, tmp, 2* pointer
1165     movd %1, %3
1166     movd %2, %4
1167     JDUP %1, %2
1168 %endmacro
1169
1170 %macro LOAD_DUP_4x8P_CONROE 8 ; 4*dst, 4*pointer
1171     movddup m%3, %6
1172     movddup m%4, %8
1173     movddup m%1, %5
1174     movddup m%2, %7
1175 %endmacro
1176
1177 %macro LOAD_DUP_4x8P_PENRYN 8
1178     ; penryn and nehalem run punpcklqdq and movddup in different units
1179     movh m%3, %6
1180     movh m%4, %8
1181     punpcklqdq m%3, m%3
1182     movddup m%1, %5
1183     punpcklqdq m%4, m%4
1184     movddup m%2, %7
1185 %endmacro
1186
1187 %macro LOAD_SUMSUB_8x2P 9
1188     LOAD_DUP_4x8P %1, %2, %3, %4, %6, %7, %8, %9
1189     DIFF_SUMSUB_SSSE3 %1, %3, %2, %4, %5
1190 %endmacro
1191
1192 %macro LOAD_SUMSUB_8x4P_SSSE3 7-11 r0, r2, 0, 0
1193 ; 4x dest, 2x tmp, 1x mul, [2* ptr], [increment?]
1194     LOAD_SUMSUB_8x2P %1, %2, %5, %6, %7, [%8], [%9], [%8+r1], [%9+r3]
1195     LOAD_SUMSUB_8x2P %3, %4, %5, %6, %7, [%8+2*r1], [%9+2*r3], [%8+r4], [%9+r5]
1196 %if %10
1197     lea %8, [%8+4*r1]
1198     lea %9, [%9+4*r3]
1199 %endif
1200 %endmacro
1201
1202 %macro LOAD_SUMSUB_16P_SSSE3 7 ; 2*dst, 2*tmp, mul, 2*ptr
1203     movddup m%1, [%7]
1204     movddup m%2, [%7+8]
1205     mova m%4, [%6]
1206     movddup m%3, m%4
1207     punpckhqdq m%4, m%4
1208     DIFF_SUMSUB_SSSE3 %1, %3, %2, %4, %5
1209 %endmacro
1210
1211 %macro LOAD_SUMSUB_16P_SSE2 7 ; 2*dst, 2*tmp, mask, 2*ptr
1212     movu  m%4, [%7]
1213     mova  m%2, [%6]
1214     DEINTB %1, %2, %3, %4, %5
1215     psubw m%1, m%3
1216     psubw m%2, m%4
1217     SUMSUB_BA w, %1, %2, %3
1218 %endmacro
1219
1220 %macro LOAD_SUMSUB_16x4P 10-13 r0, r2, none
1221 ; 8x dest, 1x tmp, 1x mul, [2* ptr] [2nd tmp]
1222     LOAD_SUMSUB_16P %1, %5, %2, %3, %10, %11, %12
1223     LOAD_SUMSUB_16P %2, %6, %3, %4, %10, %11+r1, %12+r3
1224     LOAD_SUMSUB_16P %3, %7, %4, %9, %10, %11+2*r1, %12+2*r3
1225     LOAD_SUMSUB_16P %4, %8, %13, %9, %10, %11+r4, %12+r5
1226 %endmacro
1227
1228 %macro LOAD_SUMSUB_16x2P_AVX2 9
1229 ; 2*dst, 2*tmp, mul, 4*ptr
1230     vbroadcasti128 m%1, [%6]
1231     vbroadcasti128 m%3, [%7]
1232     vbroadcasti128 m%2, [%8]
1233     vbroadcasti128 m%4, [%9]
1234     DIFF_SUMSUB_SSSE3 %1, %3, %2, %4, %5
1235 %endmacro
1236
1237 %macro LOAD_SUMSUB_16x4P_AVX2 7-11 r0, r2, 0, 0
1238 ; 4x dest, 2x tmp, 1x mul, [2* ptr], [increment?]
1239     LOAD_SUMSUB_16x2P_AVX2 %1, %2, %5, %6, %7, %8, %9, %8+r1, %9+r3
1240     LOAD_SUMSUB_16x2P_AVX2 %3, %4, %5, %6, %7, %8+2*r1, %9+2*r3, %8+r4, %9+r5
1241 %if %10
1242     lea  %8, [%8+4*r1]
1243     lea  %9, [%9+4*r3]
1244 %endif
1245 %endmacro
1246
1247 %macro LOAD_DUP_4x16P_AVX2 8 ; 4*dst, 4*pointer
1248     mova  xm%3, %6
1249     mova  xm%4, %8
1250     mova  xm%1, %5
1251     mova  xm%2, %7
1252     vpermq m%3, m%3, q0011
1253     vpermq m%4, m%4, q0011
1254     vpermq m%1, m%1, q0011
1255     vpermq m%2, m%2, q0011
1256 %endmacro
1257
1258 %macro LOAD_SUMSUB8_16x2P_AVX2 9
1259 ; 2*dst, 2*tmp, mul, 4*ptr
1260     LOAD_DUP_4x16P_AVX2 %1, %2, %3, %4, %6, %7, %8, %9
1261     DIFF_SUMSUB_SSSE3 %1, %3, %2, %4, %5
1262 %endmacro
1263
1264 %macro LOAD_SUMSUB8_16x4P_AVX2 7-11 r0, r2, 0, 0
1265 ; 4x dest, 2x tmp, 1x mul, [2* ptr], [increment?]
1266     LOAD_SUMSUB8_16x2P_AVX2 %1, %2, %5, %6, %7, [%8], [%9], [%8+r1], [%9+r3]
1267     LOAD_SUMSUB8_16x2P_AVX2 %3, %4, %5, %6, %7, [%8+2*r1], [%9+2*r3], [%8+r4], [%9+r5]
1268 %if %10
1269     lea  %8, [%8+4*r1]
1270     lea  %9, [%9+4*r3]
1271 %endif
1272 %endmacro
1273
1274 ; in: r4=3*stride1, r5=3*stride2
1275 ; in: %2 = horizontal offset
1276 ; in: %3 = whether we need to increment pix1 and pix2
1277 ; clobber: m3..m7
1278 ; out: %1 = satd
1279 %macro SATD_4x4_MMX 3
1280     %xdefine %%n nn%1
1281     %assign offset %2*SIZEOF_PIXEL
1282     LOAD_DIFF m4, m3, none, [r0+     offset], [r2+     offset]
1283     LOAD_DIFF m5, m3, none, [r0+  r1+offset], [r2+  r3+offset]
1284     LOAD_DIFF m6, m3, none, [r0+2*r1+offset], [r2+2*r3+offset]
1285     LOAD_DIFF m7, m3, none, [r0+  r4+offset], [r2+  r5+offset]
1286 %if %3
1287     lea  r0, [r0+4*r1]
1288     lea  r2, [r2+4*r3]
1289 %endif
1290     HADAMARD4_2D 4, 5, 6, 7, 3, %%n
1291     paddw m4, m6
1292     SWAP %%n, 4
1293 %endmacro
1294
1295 ; in: %1 = horizontal if 0, vertical if 1
1296 %macro SATD_8x4_SSE 8-9
1297 %if %1
1298     HADAMARD4_2D_SSE %2, %3, %4, %5, %6, amax
1299 %else
1300     HADAMARD4_V %2, %3, %4, %5, %6
1301     ; doing the abs first is a slight advantage
1302     ABSW2 m%2, m%4, m%2, m%4, m%6, m%7
1303     ABSW2 m%3, m%5, m%3, m%5, m%6, m%7
1304     HADAMARD 1, max, %2, %4, %6, %7
1305 %endif
1306 %ifnidn %9, swap
1307     paddw m%8, m%2
1308 %else
1309     SWAP %8, %2
1310 %endif
1311 %if %1
1312     paddw m%8, m%4
1313 %else
1314     HADAMARD 1, max, %3, %5, %6, %7
1315     paddw m%8, m%3
1316 %endif
1317 %endmacro
1318
1319 %macro SATD_START_MMX 0
1320     FIX_STRIDES r1, r3
1321     lea  r4, [3*r1] ; 3*stride1
1322     lea  r5, [3*r3] ; 3*stride2
1323 %endmacro
1324
1325 %macro SATD_END_MMX 0
1326 %if HIGH_BIT_DEPTH
1327     HADDUW      m0, m1
1328     movd       eax, m0
1329 %else ; !HIGH_BIT_DEPTH
1330     pshufw      m1, m0, q1032
1331     paddw       m0, m1
1332     pshufw      m1, m0, q2301
1333     paddw       m0, m1
1334     movd       eax, m0
1335     and        eax, 0xffff
1336 %endif ; HIGH_BIT_DEPTH
1337     RET
1338 %endmacro
1339
1340 ; FIXME avoid the spilling of regs to hold 3*stride.
1341 ; for small blocks on x86_32, modify pixel pointer instead.
1342
1343 ;-----------------------------------------------------------------------------
1344 ; int pixel_satd_16x16( uint8_t *, intptr_t, uint8_t *, intptr_t )
1345 ;-----------------------------------------------------------------------------
1346 INIT_MMX mmx2
1347 cglobal pixel_satd_16x4_internal
1348     SATD_4x4_MMX m2,  0, 0
1349     SATD_4x4_MMX m1,  4, 0
1350     paddw        m0, m2
1351     SATD_4x4_MMX m2,  8, 0
1352     paddw        m0, m1
1353     SATD_4x4_MMX m1, 12, 0
1354     paddw        m0, m2
1355     paddw        m0, m1
1356     ret
1357
1358 cglobal pixel_satd_8x8_internal
1359     SATD_4x4_MMX m2,  0, 0
1360     SATD_4x4_MMX m1,  4, 1
1361     paddw        m0, m2
1362     paddw        m0, m1
1363 pixel_satd_8x4_internal_mmx2:
1364     SATD_4x4_MMX m2,  0, 0
1365     SATD_4x4_MMX m1,  4, 0
1366     paddw        m0, m2
1367     paddw        m0, m1
1368     ret
1369
1370 %if HIGH_BIT_DEPTH
1371 %macro SATD_MxN_MMX 3
1372 cglobal pixel_satd_%1x%2, 4,7
1373     SATD_START_MMX
1374     pxor   m0, m0
1375     call pixel_satd_%1x%3_internal_mmx2
1376     HADDUW m0, m1
1377     movd  r6d, m0
1378 %rep %2/%3-1
1379     pxor   m0, m0
1380     lea    r0, [r0+4*r1]
1381     lea    r2, [r2+4*r3]
1382     call pixel_satd_%1x%3_internal_mmx2
1383     movd   m2, r4
1384     HADDUW m0, m1
1385     movd   r4, m0
1386     add    r6, r4
1387     movd   r4, m2
1388 %endrep
1389     movifnidn eax, r6d
1390     RET
1391 %endmacro
1392
1393 SATD_MxN_MMX 16, 16, 4
1394 SATD_MxN_MMX 16,  8, 4
1395 SATD_MxN_MMX  8, 16, 8
1396 %endif ; HIGH_BIT_DEPTH
1397
1398 %if HIGH_BIT_DEPTH == 0
1399 cglobal pixel_satd_16x16, 4,6
1400     SATD_START_MMX
1401     pxor   m0, m0
1402 %rep 3
1403     call pixel_satd_16x4_internal_mmx2
1404     lea  r0, [r0+4*r1]
1405     lea  r2, [r2+4*r3]
1406 %endrep
1407     call pixel_satd_16x4_internal_mmx2
1408     HADDUW m0, m1
1409     movd  eax, m0
1410     RET
1411
1412 cglobal pixel_satd_16x8, 4,6
1413     SATD_START_MMX
1414     pxor   m0, m0
1415     call pixel_satd_16x4_internal_mmx2
1416     lea  r0, [r0+4*r1]
1417     lea  r2, [r2+4*r3]
1418     call pixel_satd_16x4_internal_mmx2
1419     SATD_END_MMX
1420
1421 cglobal pixel_satd_8x16, 4,6
1422     SATD_START_MMX
1423     pxor   m0, m0
1424     call pixel_satd_8x8_internal_mmx2
1425     lea  r0, [r0+4*r1]
1426     lea  r2, [r2+4*r3]
1427     call pixel_satd_8x8_internal_mmx2
1428     SATD_END_MMX
1429 %endif ; !HIGH_BIT_DEPTH
1430
1431 cglobal pixel_satd_8x8, 4,6
1432     SATD_START_MMX
1433     pxor   m0, m0
1434     call pixel_satd_8x8_internal_mmx2
1435     SATD_END_MMX
1436
1437 cglobal pixel_satd_8x4, 4,6
1438     SATD_START_MMX
1439     pxor   m0, m0
1440     call pixel_satd_8x4_internal_mmx2
1441     SATD_END_MMX
1442
1443 cglobal pixel_satd_4x16, 4,6
1444     SATD_START_MMX
1445     SATD_4x4_MMX m0, 0, 1
1446     SATD_4x4_MMX m1, 0, 1
1447     paddw  m0, m1
1448     SATD_4x4_MMX m1, 0, 1
1449     paddw  m0, m1
1450     SATD_4x4_MMX m1, 0, 0
1451     paddw  m0, m1
1452     SATD_END_MMX
1453
1454 cglobal pixel_satd_4x8, 4,6
1455     SATD_START_MMX
1456     SATD_4x4_MMX m0, 0, 1
1457     SATD_4x4_MMX m1, 0, 0
1458     paddw  m0, m1
1459     SATD_END_MMX
1460
1461 cglobal pixel_satd_4x4, 4,6
1462     SATD_START_MMX
1463     SATD_4x4_MMX m0, 0, 0
1464     SATD_END_MMX
1465
1466 %macro SATD_START_SSE2 2-3 0
1467     FIX_STRIDES r1, r3
1468 %if HIGH_BIT_DEPTH && %3
1469     pxor    %2, %2
1470 %elif cpuflag(ssse3) && notcpuflag(atom)
1471 %if mmsize==32
1472     mova    %2, [hmul_16p]
1473 %else
1474     mova    %2, [hmul_8p]
1475 %endif
1476 %endif
1477     lea     r4, [3*r1]
1478     lea     r5, [3*r3]
1479     pxor    %1, %1
1480 %endmacro
1481
1482 %macro SATD_END_SSE2 1-2
1483 %if HIGH_BIT_DEPTH
1484     HADDUW  %1, xm0
1485 %if %0 == 2
1486     paddd   %1, %2
1487 %endif
1488 %else
1489     HADDW   %1, xm7
1490 %endif
1491     movd   eax, %1
1492     RET
1493 %endmacro
1494
1495 %macro SATD_ACCUM 3
1496 %if HIGH_BIT_DEPTH
1497     HADDUW %1, %2
1498     paddd  %3, %1
1499     pxor   %1, %1
1500 %endif
1501 %endmacro
1502
1503 %macro BACKUP_POINTERS 0
1504 %if ARCH_X86_64
1505 %if WIN64
1506     PUSH r7
1507 %endif
1508     mov     r6, r0
1509     mov     r7, r2
1510 %endif
1511 %endmacro
1512
1513 %macro RESTORE_AND_INC_POINTERS 0
1514 %if ARCH_X86_64
1515     lea     r0, [r6+8*SIZEOF_PIXEL]
1516     lea     r2, [r7+8*SIZEOF_PIXEL]
1517 %if WIN64
1518     POP r7
1519 %endif
1520 %else
1521     mov     r0, r0mp
1522     mov     r2, r2mp
1523     add     r0, 8*SIZEOF_PIXEL
1524     add     r2, 8*SIZEOF_PIXEL
1525 %endif
1526 %endmacro
1527
1528 %macro SATD_4x8_SSE 3
1529 %if HIGH_BIT_DEPTH
1530     movh    m0, [r0+0*r1]
1531     movh    m4, [r2+0*r3]
1532     movh    m1, [r0+1*r1]
1533     movh    m5, [r2+1*r3]
1534     movhps  m0, [r0+4*r1]
1535     movhps  m4, [r2+4*r3]
1536     movh    m2, [r0+2*r1]
1537     movh    m6, [r2+2*r3]
1538     psubw   m0, m4
1539     movh    m3, [r0+r4]
1540     movh    m4, [r2+r5]
1541     lea     r0, [r0+4*r1]
1542     lea     r2, [r2+4*r3]
1543     movhps  m1, [r0+1*r1]
1544     movhps  m5, [r2+1*r3]
1545     movhps  m2, [r0+2*r1]
1546     movhps  m6, [r2+2*r3]
1547     psubw   m1, m5
1548     movhps  m3, [r0+r4]
1549     movhps  m4, [r2+r5]
1550     psubw   m2, m6
1551     psubw   m3, m4
1552 %else ; !HIGH_BIT_DEPTH
1553     movd m4, [r2]
1554     movd m5, [r2+r3]
1555     movd m6, [r2+2*r3]
1556     add r2, r5
1557     movd m0, [r0]
1558     movd m1, [r0+r1]
1559     movd m2, [r0+2*r1]
1560     add r0, r4
1561     movd m3, [r2+r3]
1562     JDUP m4, m3
1563     movd m3, [r0+r1]
1564     JDUP m0, m3
1565     movd m3, [r2+2*r3]
1566     JDUP m5, m3
1567     movd m3, [r0+2*r1]
1568     JDUP m1, m3
1569 %if %1==0 && %2==1
1570     mova m3, [hmul_4p]
1571     DIFFOP 0, 4, 1, 5, 3
1572 %else
1573     DIFFOP 0, 4, 1, 5, 7
1574 %endif
1575     movd m5, [r2]
1576     add r2, r5
1577     movd m3, [r0]
1578     add r0, r4
1579     movd m4, [r2]
1580     JDUP m6, m4
1581     movd m4, [r0]
1582     JDUP m2, m4
1583     movd m4, [r2+r3]
1584     JDUP m5, m4
1585     movd m4, [r0+r1]
1586     JDUP m3, m4
1587 %if %1==0 && %2==1
1588     mova m4, [hmul_4p]
1589     DIFFOP 2, 6, 3, 5, 4
1590 %else
1591     DIFFOP 2, 6, 3, 5, 7
1592 %endif
1593 %endif ; HIGH_BIT_DEPTH
1594     SATD_8x4_SSE %1, 0, 1, 2, 3, 4, 5, 7, %3
1595 %endmacro
1596
1597 ;-----------------------------------------------------------------------------
1598 ; int pixel_satd_8x4( uint8_t *, intptr_t, uint8_t *, intptr_t )
1599 ;-----------------------------------------------------------------------------
1600 %macro SATDS_SSE2 0
1601 %define vertical ((notcpuflag(ssse3) || cpuflag(atom)) || HIGH_BIT_DEPTH)
1602
1603 %if vertical==0 || HIGH_BIT_DEPTH
1604 cglobal pixel_satd_4x4, 4, 6, 6
1605     SATD_START_MMX
1606     mova m4, [hmul_4p]
1607     LOAD_DUP_2x4P m2, m5, [r2], [r2+r3]
1608     LOAD_DUP_2x4P m3, m5, [r2+2*r3], [r2+r5]
1609     LOAD_DUP_2x4P m0, m5, [r0], [r0+r1]
1610     LOAD_DUP_2x4P m1, m5, [r0+2*r1], [r0+r4]
1611     DIFF_SUMSUB_SSSE3 0, 2, 1, 3, 4
1612     HADAMARD 0, sumsub, 0, 1, 2, 3
1613     HADAMARD 4, sumsub, 0, 1, 2, 3
1614     HADAMARD 1, amax, 0, 1, 2, 3
1615     HADDW m0, m1
1616     movd eax, m0
1617     RET
1618 %endif
1619
1620 cglobal pixel_satd_4x8, 4, 6, 8
1621     SATD_START_MMX
1622 %if vertical==0
1623     mova m7, [hmul_4p]
1624 %endif
1625     SATD_4x8_SSE vertical, 0, swap
1626     HADDW m7, m1
1627     movd eax, m7
1628     RET
1629
1630 cglobal pixel_satd_4x16, 4, 6, 8
1631     SATD_START_MMX
1632 %if vertical==0
1633     mova m7, [hmul_4p]
1634 %endif
1635     SATD_4x8_SSE vertical, 0, swap
1636     lea r0, [r0+r1*2*SIZEOF_PIXEL]
1637     lea r2, [r2+r3*2*SIZEOF_PIXEL]
1638     SATD_4x8_SSE vertical, 1, add
1639     HADDW m7, m1
1640     movd eax, m7
1641     RET
1642
1643 cglobal pixel_satd_8x8_internal
1644     LOAD_SUMSUB_8x4P 0, 1, 2, 3, 4, 5, 7, r0, r2, 1, 0
1645     SATD_8x4_SSE vertical, 0, 1, 2, 3, 4, 5, 6
1646 %%pixel_satd_8x4_internal:
1647     LOAD_SUMSUB_8x4P 0, 1, 2, 3, 4, 5, 7, r0, r2, 1, 0
1648     SATD_8x4_SSE vertical, 0, 1, 2, 3, 4, 5, 6
1649     ret
1650
1651 ; 16x8 regresses on phenom win64, 16x16 is almost the same (too many spilled registers)
1652 ; These aren't any faster on AVX systems with fast movddup (Bulldozer, Sandy Bridge)
1653 %if HIGH_BIT_DEPTH == 0 && UNIX64 && notcpuflag(avx)
1654 cglobal pixel_satd_16x4_internal
1655     LOAD_SUMSUB_16x4P 0, 1, 2, 3, 4, 8, 5, 9, 6, 7, r0, r2, 11
1656     lea  r2, [r2+4*r3]
1657     lea  r0, [r0+4*r1]
1658     ; always use horizontal mode here
1659     SATD_8x4_SSE 0, 0, 1, 2, 3, 6, 11, 10
1660     SATD_8x4_SSE 0, 4, 8, 5, 9, 6, 3, 10
1661     ret
1662
1663 cglobal pixel_satd_16x8, 4,6,12
1664     SATD_START_SSE2 m10, m7
1665 %if vertical
1666     mova m7, [pw_00ff]
1667 %endif
1668     jmp %%pixel_satd_16x8_internal
1669
1670 cglobal pixel_satd_16x16, 4,6,12
1671     SATD_START_SSE2 m10, m7
1672 %if vertical
1673     mova m7, [pw_00ff]
1674 %endif
1675     call pixel_satd_16x4_internal
1676     call pixel_satd_16x4_internal
1677 %%pixel_satd_16x8_internal:
1678     call pixel_satd_16x4_internal
1679     call pixel_satd_16x4_internal
1680     SATD_END_SSE2 m10
1681 %else
1682 cglobal pixel_satd_16x8, 4,6,8
1683     SATD_START_SSE2 m6, m7
1684     BACKUP_POINTERS
1685     call pixel_satd_8x8_internal
1686     RESTORE_AND_INC_POINTERS
1687     call pixel_satd_8x8_internal
1688     SATD_END_SSE2 m6
1689
1690 cglobal pixel_satd_16x16, 4,6,8
1691     SATD_START_SSE2 m6, m7, 1
1692     BACKUP_POINTERS
1693     call pixel_satd_8x8_internal
1694     call pixel_satd_8x8_internal
1695     SATD_ACCUM m6, m0, m7
1696     RESTORE_AND_INC_POINTERS
1697     call pixel_satd_8x8_internal
1698     call pixel_satd_8x8_internal
1699     SATD_END_SSE2 m6, m7
1700 %endif
1701
1702 cglobal pixel_satd_8x16, 4,6,8
1703     SATD_START_SSE2 m6, m7
1704     call pixel_satd_8x8_internal
1705     call pixel_satd_8x8_internal
1706     SATD_END_SSE2 m6
1707
1708 cglobal pixel_satd_8x8, 4,6,8
1709     SATD_START_SSE2 m6, m7
1710     call pixel_satd_8x8_internal
1711     SATD_END_SSE2 m6
1712
1713 cglobal pixel_satd_8x4, 4,6,8
1714     SATD_START_SSE2 m6, m7
1715     call %%pixel_satd_8x4_internal
1716     SATD_END_SSE2 m6
1717 %endmacro ; SATDS_SSE2
1718
1719 %macro SA8D_INTER 0
1720 %if ARCH_X86_64
1721     %define lh m10
1722     %define rh m0
1723 %else
1724     %define lh m0
1725     %define rh [esp+48]
1726 %endif
1727 %if HIGH_BIT_DEPTH
1728     HADDUW  m0, m1
1729     paddd   lh, rh
1730 %else
1731     paddusw lh, rh
1732 %endif ; HIGH_BIT_DEPTH
1733 %endmacro
1734
1735 %macro SA8D 0
1736 ; sse2 doesn't seem to like the horizontal way of doing things
1737 %define vertical ((notcpuflag(ssse3) || cpuflag(atom)) || HIGH_BIT_DEPTH)
1738
1739 %if ARCH_X86_64
1740 ;-----------------------------------------------------------------------------
1741 ; int pixel_sa8d_8x8( uint8_t *, intptr_t, uint8_t *, intptr_t )
1742 ;-----------------------------------------------------------------------------
1743 cglobal pixel_sa8d_8x8_internal
1744     lea  r6, [r0+4*r1]
1745     lea  r7, [r2+4*r3]
1746     LOAD_SUMSUB_8x4P 0, 1, 2, 8, 5, 6, 7, r0, r2
1747     LOAD_SUMSUB_8x4P 4, 5, 3, 9, 11, 6, 7, r6, r7
1748 %if vertical
1749     HADAMARD8_2D 0, 1, 2, 8, 4, 5, 3, 9, 6, amax
1750 %else ; non-sse2
1751     HADAMARD8_2D_HMUL 0, 1, 2, 8, 4, 5, 3, 9, 6, 11
1752 %endif
1753     paddw m0, m1
1754     paddw m0, m2
1755     paddw m0, m8
1756     SAVE_MM_PERMUTATION
1757     ret
1758
1759 cglobal pixel_sa8d_8x8, 4,8,12
1760     FIX_STRIDES r1, r3
1761     lea  r4, [3*r1]
1762     lea  r5, [3*r3]
1763 %if vertical == 0
1764     mova m7, [hmul_8p]
1765 %endif
1766     call pixel_sa8d_8x8_internal
1767 %if HIGH_BIT_DEPTH
1768     HADDUW m0, m1
1769 %else
1770     HADDW m0, m1
1771 %endif ; HIGH_BIT_DEPTH
1772     movd eax, m0
1773     add eax, 1
1774     shr eax, 1
1775     RET
1776
1777 cglobal pixel_sa8d_16x16, 4,8,12
1778     FIX_STRIDES r1, r3
1779     lea  r4, [3*r1]
1780     lea  r5, [3*r3]
1781 %if vertical == 0
1782     mova m7, [hmul_8p]
1783 %endif
1784     call pixel_sa8d_8x8_internal ; pix[0]
1785     add  r2, 8*SIZEOF_PIXEL
1786     add  r0, 8*SIZEOF_PIXEL
1787 %if HIGH_BIT_DEPTH
1788     HADDUW m0, m1
1789 %endif
1790     mova m10, m0
1791     call pixel_sa8d_8x8_internal ; pix[8]
1792     lea  r2, [r2+8*r3]
1793     lea  r0, [r0+8*r1]
1794     SA8D_INTER
1795     call pixel_sa8d_8x8_internal ; pix[8*stride+8]
1796     sub  r2, 8*SIZEOF_PIXEL
1797     sub  r0, 8*SIZEOF_PIXEL
1798     SA8D_INTER
1799     call pixel_sa8d_8x8_internal ; pix[8*stride]
1800     SA8D_INTER
1801     SWAP 0, 10
1802 %if HIGH_BIT_DEPTH == 0
1803     HADDUW m0, m1
1804 %endif
1805     movd eax, m0
1806     add  eax, 1
1807     shr  eax, 1
1808     RET
1809
1810 %else ; ARCH_X86_32
1811 %if mmsize == 16
1812 cglobal pixel_sa8d_8x8_internal
1813     %define spill0 [esp+4]
1814     %define spill1 [esp+20]
1815     %define spill2 [esp+36]
1816 %if vertical
1817     LOAD_DIFF_8x4P 0, 1, 2, 3, 4, 5, 6, r0, r2, 1
1818     HADAMARD4_2D 0, 1, 2, 3, 4
1819     movdqa spill0, m3
1820     LOAD_DIFF_8x4P 4, 5, 6, 7, 3, 3, 2, r0, r2, 1
1821     HADAMARD4_2D 4, 5, 6, 7, 3
1822     HADAMARD2_2D 0, 4, 1, 5, 3, qdq, amax
1823     movdqa m3, spill0
1824     paddw m0, m1
1825     HADAMARD2_2D 2, 6, 3, 7, 5, qdq, amax
1826 %else ; mmsize == 8
1827     mova m7, [hmul_8p]
1828     LOAD_SUMSUB_8x4P 0, 1, 2, 3, 5, 6, 7, r0, r2, 1
1829     ; could do first HADAMARD4_V here to save spilling later
1830     ; surprisingly, not a win on conroe or even p4
1831     mova spill0, m2
1832     mova spill1, m3
1833     mova spill2, m1
1834     SWAP 1, 7
1835     LOAD_SUMSUB_8x4P 4, 5, 6, 7, 2, 3, 1, r0, r2, 1
1836     HADAMARD4_V 4, 5, 6, 7, 3
1837     mova m1, spill2
1838     mova m2, spill0
1839     mova m3, spill1
1840     mova spill0, m6
1841     mova spill1, m7
1842     HADAMARD4_V 0, 1, 2, 3, 7
1843     SUMSUB_BADC w, 0, 4, 1, 5, 7
1844     HADAMARD 2, sumsub, 0, 4, 7, 6
1845     HADAMARD 2, sumsub, 1, 5, 7, 6
1846     HADAMARD 1, amax, 0, 4, 7, 6
1847     HADAMARD 1, amax, 1, 5, 7, 6
1848     mova m6, spill0
1849     mova m7, spill1
1850     paddw m0, m1
1851     SUMSUB_BADC w, 2, 6, 3, 7, 4
1852     HADAMARD 2, sumsub, 2, 6, 4, 5
1853     HADAMARD 2, sumsub, 3, 7, 4, 5
1854     HADAMARD 1, amax, 2, 6, 4, 5
1855     HADAMARD 1, amax, 3, 7, 4, 5
1856 %endif ; sse2/non-sse2
1857     paddw m0, m2
1858     paddw m0, m3
1859     SAVE_MM_PERMUTATION
1860     ret
1861 %endif ; ifndef mmx2
1862
1863 cglobal pixel_sa8d_8x8, 4,7
1864     FIX_STRIDES r1, r3
1865     mov    r6, esp
1866     and   esp, ~15
1867     sub   esp, 48
1868     lea    r4, [3*r1]
1869     lea    r5, [3*r3]
1870     call pixel_sa8d_8x8_internal
1871 %if HIGH_BIT_DEPTH
1872     HADDUW m0, m1
1873 %else
1874     HADDW  m0, m1
1875 %endif ; HIGH_BIT_DEPTH
1876     movd  eax, m0
1877     add   eax, 1
1878     shr   eax, 1
1879     mov   esp, r6
1880     RET
1881
1882 cglobal pixel_sa8d_16x16, 4,7
1883     FIX_STRIDES r1, r3
1884     mov  r6, esp
1885     and  esp, ~15
1886     sub  esp, 64
1887     lea  r4, [3*r1]
1888     lea  r5, [3*r3]
1889     call pixel_sa8d_8x8_internal
1890 %if mmsize == 8
1891     lea  r0, [r0+4*r1]
1892     lea  r2, [r2+4*r3]
1893 %endif
1894 %if HIGH_BIT_DEPTH
1895     HADDUW m0, m1
1896 %endif
1897     mova [esp+48], m0
1898     call pixel_sa8d_8x8_internal
1899     mov  r0, [r6+20]
1900     mov  r2, [r6+28]
1901     add  r0, 8*SIZEOF_PIXEL
1902     add  r2, 8*SIZEOF_PIXEL
1903     SA8D_INTER
1904     mova [esp+48], m0
1905     call pixel_sa8d_8x8_internal
1906 %if mmsize == 8
1907     lea  r0, [r0+4*r1]
1908     lea  r2, [r2+4*r3]
1909 %else
1910     SA8D_INTER
1911 %endif
1912     mova [esp+64-mmsize], m0
1913     call pixel_sa8d_8x8_internal
1914 %if HIGH_BIT_DEPTH
1915     SA8D_INTER
1916 %else ; !HIGH_BIT_DEPTH
1917     paddusw m0, [esp+64-mmsize]
1918 %if mmsize == 16
1919     HADDUW m0, m1
1920 %else
1921     mova m2, [esp+48]
1922     pxor m7, m7
1923     mova m1, m0
1924     mova m3, m2
1925     punpcklwd m0, m7
1926     punpckhwd m1, m7
1927     punpcklwd m2, m7
1928     punpckhwd m3, m7
1929     paddd m0, m1
1930     paddd m2, m3
1931     paddd m0, m2
1932     HADDD m0, m1
1933 %endif
1934 %endif ; HIGH_BIT_DEPTH
1935     movd eax, m0
1936     add  eax, 1
1937     shr  eax, 1
1938     mov  esp, r6
1939     RET
1940 %endif ; !ARCH_X86_64
1941 %endmacro ; SA8D
1942
1943 ;=============================================================================
1944 ; SA8D_SATD
1945 ;=============================================================================
1946
1947 ; %1: vertical/horizontal mode
1948 ; %2-%5: sa8d output regs (m0,m1,m2,m3,m4,m5,m8,m9)
1949 ; m10: satd result
1950 ; m6, m11-15: tmp regs
1951 %macro SA8D_SATD_8x4 5
1952 %if %1
1953     LOAD_DIFF_8x4P %2, %3, %4, %5, 6, 11, 7, r0, r2, 1
1954     HADAMARD   0, sumsub, %2, %3, 6
1955     HADAMARD   0, sumsub, %4, %5, 6
1956     SBUTTERFLY        wd, %2, %3, 6
1957     SBUTTERFLY        wd, %4, %5, 6
1958     HADAMARD2_2D  %2, %4, %3, %5, 6, dq
1959
1960     mova   m12, m%2
1961     mova   m13, m%3
1962     mova   m14, m%4
1963     mova   m15, m%5
1964     HADAMARD 0, sumsub, %2, %3, 6
1965     HADAMARD 0, sumsub, %4, %5, 6
1966     SBUTTERFLY     qdq, 12, 13, 6
1967     HADAMARD   0, amax, 12, 13, 6
1968     SBUTTERFLY     qdq, 14, 15, 6
1969     paddw m10, m12
1970     HADAMARD   0, amax, 14, 15, 6
1971     paddw m10, m14
1972 %else
1973     LOAD_SUMSUB_8x4P %2, %3, %4, %5, 6, 11, 7, r0, r2, 1
1974     HADAMARD4_V %2, %3, %4, %5, 6
1975
1976     pabsw    m12, m%2 ; doing the abs first is a slight advantage
1977     pabsw    m14, m%4
1978     pabsw    m13, m%3
1979     pabsw    m15, m%5
1980     HADAMARD 1, max, 12, 14, 6, 11
1981     paddw    m10, m12
1982     HADAMARD 1, max, 13, 15, 6, 11
1983     paddw    m10, m13
1984 %endif
1985 %endmacro ; SA8D_SATD_8x4
1986
1987 ; %1: add spilled regs?
1988 ; %2: spill regs?
1989 %macro SA8D_SATD_ACCUM 2
1990 %if HIGH_BIT_DEPTH
1991     pmaddwd m10, [pw_1]
1992     HADDUWD  m0, m1
1993 %if %1
1994     paddd   m10, temp1
1995     paddd    m0, temp0
1996 %endif
1997 %if %2
1998     mova  temp1, m10
1999     pxor    m10, m10
2000 %endif
2001 %elif %1
2002     paddw    m0, temp0
2003 %endif
2004 %if %2
2005     mova  temp0, m0
2006 %endif
2007 %endmacro
2008
2009 %macro SA8D_SATD 0
2010 %define vertical ((notcpuflag(ssse3) || cpuflag(atom)) || HIGH_BIT_DEPTH)
2011 cglobal pixel_sa8d_satd_8x8_internal
2012     SA8D_SATD_8x4 vertical, 0, 1, 2, 3
2013     SA8D_SATD_8x4 vertical, 4, 5, 8, 9
2014
2015 %if vertical ; sse2-style
2016     HADAMARD2_2D 0, 4, 2, 8, 6, qdq, amax
2017     HADAMARD2_2D 1, 5, 3, 9, 6, qdq, amax
2018 %else        ; complete sa8d
2019     SUMSUB_BADC w, 0, 4, 1, 5, 12
2020     HADAMARD 2, sumsub, 0, 4, 12, 11
2021     HADAMARD 2, sumsub, 1, 5, 12, 11
2022     SUMSUB_BADC w, 2, 8, 3, 9, 12
2023     HADAMARD 2, sumsub, 2, 8, 12, 11
2024     HADAMARD 2, sumsub, 3, 9, 12, 11
2025     HADAMARD 1, amax, 0, 4, 12, 11
2026     HADAMARD 1, amax, 1, 5, 12, 4
2027     HADAMARD 1, amax, 2, 8, 12, 4
2028     HADAMARD 1, amax, 3, 9, 12, 4
2029 %endif
2030
2031     ; create sa8d sub results
2032     paddw    m1, m2
2033     paddw    m0, m3
2034     paddw    m0, m1
2035
2036     SAVE_MM_PERMUTATION
2037     ret
2038
2039 ;-------------------------------------------------------------------------------
2040 ; uint64_t pixel_sa8d_satd_16x16( pixel *, intptr_t, pixel *, intptr_t )
2041 ;-------------------------------------------------------------------------------
2042 cglobal pixel_sa8d_satd_16x16, 4,8-(mmsize/32),16,SIZEOF_PIXEL*mmsize
2043     %define temp0 [rsp+0*mmsize]
2044     %define temp1 [rsp+1*mmsize]
2045     FIX_STRIDES r1, r3
2046 %if vertical==0
2047     mova     m7, [hmul_8p]
2048 %endif
2049     lea      r4, [3*r1]
2050     lea      r5, [3*r3]
2051     pxor    m10, m10
2052
2053 %if mmsize==32
2054     call pixel_sa8d_satd_8x8_internal
2055     SA8D_SATD_ACCUM 0, 1
2056     call pixel_sa8d_satd_8x8_internal
2057     SA8D_SATD_ACCUM 1, 0
2058     vextracti128 xm1, m0, 1
2059     vextracti128 xm2, m10, 1
2060     paddw   xm0, xm1
2061     paddw  xm10, xm2
2062 %else
2063     lea      r6, [r2+8*SIZEOF_PIXEL]
2064     lea      r7, [r0+8*SIZEOF_PIXEL]
2065
2066     call pixel_sa8d_satd_8x8_internal
2067     SA8D_SATD_ACCUM 0, 1
2068     call pixel_sa8d_satd_8x8_internal
2069     SA8D_SATD_ACCUM 1, 1
2070
2071     mov      r0, r7
2072     mov      r2, r6
2073
2074     call pixel_sa8d_satd_8x8_internal
2075     SA8D_SATD_ACCUM 1, 1
2076     call pixel_sa8d_satd_8x8_internal
2077     SA8D_SATD_ACCUM 1, 0
2078 %endif
2079
2080 ; xop already has fast horizontal sums
2081 %if cpuflag(sse4) && notcpuflag(xop) && HIGH_BIT_DEPTH==0
2082     pmaddwd xm10, [pw_1]
2083     HADDUWD xm0, xm1
2084     phaddd  xm0, xm10       ;  sa8d1  sa8d2  satd1  satd2
2085     pshufd  xm1, xm0, q2301 ;  sa8d2  sa8d1  satd2  satd1
2086     paddd   xm0, xm1        ;   sa8d   sa8d   satd   satd
2087     movd    r0d, xm0
2088     pextrd  eax, xm0, 2
2089 %else
2090 %if HIGH_BIT_DEPTH
2091     HADDD   xm0, xm1
2092     HADDD  xm10, xm2
2093 %else
2094     HADDUW  xm0, xm1
2095     HADDW  xm10, xm2
2096 %endif
2097     movd    r0d, xm0
2098     movd    eax, xm10
2099 %endif
2100     add     r0d, 1
2101     shl     rax, 32
2102     shr     r0d, 1
2103     or      rax, r0
2104     RET
2105 %endmacro ; SA8D_SATD
2106
2107 ;=============================================================================
2108 ; INTRA SATD
2109 ;=============================================================================
2110
2111 %macro HSUMSUB2 8
2112     pshufd %4, %2, %7
2113     pshufd %5, %3, %7
2114     %1     %2, %8
2115     %1     %6, %8
2116     paddw  %2, %4
2117     paddw  %3, %5
2118 %endmacro
2119
2120 ; intra_sa8d_x3_8x8 and intra_satd_x3_4x4 are obsoleted by x9 on ssse3+,
2121 ; and are only retained for old cpus.
2122 %macro INTRA_SA8D_SSE2 0
2123 %if ARCH_X86_64
2124 ;-----------------------------------------------------------------------------
2125 ; void intra_sa8d_x3_8x8( uint8_t *fenc, uint8_t edge[36], int *res )
2126 ;-----------------------------------------------------------------------------
2127 cglobal intra_sa8d_x3_8x8, 3,3,14
2128     ; 8x8 hadamard
2129     pxor        m8, m8
2130     movq        m0, [r0+0*FENC_STRIDE]
2131     movq        m1, [r0+1*FENC_STRIDE]
2132     movq        m2, [r0+2*FENC_STRIDE]
2133     movq        m3, [r0+3*FENC_STRIDE]
2134     movq        m4, [r0+4*FENC_STRIDE]
2135     movq        m5, [r0+5*FENC_STRIDE]
2136     movq        m6, [r0+6*FENC_STRIDE]
2137     movq        m7, [r0+7*FENC_STRIDE]
2138     punpcklbw   m0, m8
2139     punpcklbw   m1, m8
2140     punpcklbw   m2, m8
2141     punpcklbw   m3, m8
2142     punpcklbw   m4, m8
2143     punpcklbw   m5, m8
2144     punpcklbw   m6, m8
2145     punpcklbw   m7, m8
2146
2147     HADAMARD8_2D 0, 1, 2, 3, 4, 5, 6, 7, 8
2148
2149     ABSW2       m8,  m9,  m2, m3, m2, m3
2150     ABSW2       m10, m11, m4, m5, m4, m5
2151     paddusw     m8,  m10
2152     paddusw     m9,  m11
2153     ABSW2       m10, m11, m6, m7, m6, m7
2154     ABSW        m13, m1,  m1
2155     paddusw     m10, m11
2156     paddusw     m8,  m9
2157     paddusw     m13, m10
2158     paddusw     m13, m8
2159
2160     ; 1D hadamard of edges
2161     movq        m8,  [r1+7]
2162     movq        m9,  [r1+16]
2163     pxor        m10, m10
2164     punpcklbw   m8,  m10
2165     punpcklbw   m9,  m10
2166     HSUMSUB2 pmullw, m8, m9, m10, m11, m11, q1032, [pw_ppppmmmm]
2167     HSUMSUB2 pmullw, m8, m9, m10, m11, m11, q2301, [pw_ppmmppmm]
2168     pshuflw     m10, m8,  q2301
2169     pshuflw     m11, m9,  q2301
2170     pshufhw     m10, m10, q2301
2171     pshufhw     m11, m11, q2301
2172     pmullw      m8,  [pw_pmpmpmpm]
2173     pmullw      m11, [pw_pmpmpmpm]
2174     paddw       m8,  m10
2175     paddw       m9,  m11
2176
2177     ; differences
2178     paddw       m10, m8, m9
2179     paddw       m10, [pw_8]
2180     pand        m10, [sw_f0]
2181     psllw       m10, 2 ; dc
2182
2183     psllw       m8,  3 ; left edge
2184     psubw       m8,  m0
2185     psubw       m10, m0
2186     ABSW2       m8, m10, m8, m10, m11, m12 ; 1x8 sum
2187     paddusw     m8,  m13
2188     paddusw     m13, m10
2189     punpcklwd   m0,  m1
2190     punpcklwd   m2,  m3
2191     punpcklwd   m4,  m5
2192     punpcklwd   m6,  m7
2193     punpckldq   m0,  m2
2194     punpckldq   m4,  m6
2195     punpcklqdq  m0,  m4 ; transpose
2196     psllw       m9,  3 ; top edge
2197     psrldq      m2,  m13, 2 ; 8x7 sum
2198     psubw       m0,  m9  ; 8x1 sum
2199     ABSW        m0,  m0,  m9
2200     paddusw     m2,  m0
2201
2202     ; 3x HADDW
2203     movdqa      m7,  [pw_1]
2204     pmaddwd     m2,  m7
2205     pmaddwd     m8,  m7
2206     pmaddwd     m13, m7
2207     punpckhdq   m3,  m2, m8
2208     punpckldq   m2,  m8
2209     pshufd      m5,  m13, q3311
2210     paddd       m2,  m3
2211     paddd       m5,  m13
2212     punpckhqdq  m0,  m2, m5
2213     punpcklqdq  m2,  m5
2214     pavgw       m0,  m2
2215     pxor        m1,  m1
2216     pavgw       m0,  m1
2217     movq      [r2], m0 ; i8x8_v, i8x8_h
2218     psrldq      m0, 8
2219     movd    [r2+8], m0 ; i8x8_dc
2220     RET
2221 %endif ; ARCH_X86_64
2222 %endmacro ; INTRA_SA8D_SSE2
2223
2224 ; in: r0 = fenc
2225 ; out: m0..m3 = hadamard coefs
2226 INIT_MMX
2227 cglobal hadamard_load
2228 ; not really a global, but otherwise cycles get attributed to the wrong function in profiling
2229 %if HIGH_BIT_DEPTH
2230     mova        m0, [r0+0*FENC_STRIDEB]
2231     mova        m1, [r0+1*FENC_STRIDEB]
2232     mova        m2, [r0+2*FENC_STRIDEB]
2233     mova        m3, [r0+3*FENC_STRIDEB]
2234 %else
2235     pxor        m7, m7
2236     movd        m0, [r0+0*FENC_STRIDE]
2237     movd        m1, [r0+1*FENC_STRIDE]
2238     movd        m2, [r0+2*FENC_STRIDE]
2239     movd        m3, [r0+3*FENC_STRIDE]
2240     punpcklbw   m0, m7
2241     punpcklbw   m1, m7
2242     punpcklbw   m2, m7
2243     punpcklbw   m3, m7
2244 %endif
2245     HADAMARD4_2D 0, 1, 2, 3, 4
2246     SAVE_MM_PERMUTATION
2247     ret
2248
2249 %macro SCALAR_HADAMARD 4-5 ; direction, offset, 3x tmp
2250 %ifidn %1, top
2251 %if HIGH_BIT_DEPTH
2252     mova        %3, [r1+%2*SIZEOF_PIXEL-FDEC_STRIDEB]
2253 %else
2254     movd        %3, [r1+%2*SIZEOF_PIXEL-FDEC_STRIDEB]
2255     pxor        %5, %5
2256     punpcklbw   %3, %5
2257 %endif
2258 %else ; left
2259 %ifnidn %2, 0
2260     shl         %2d, 5 ; log(FDEC_STRIDEB)
2261 %endif
2262     movd        %3, [r1+%2*SIZEOF_PIXEL-4+1*FDEC_STRIDEB]
2263     pinsrw      %3, [r1+%2*SIZEOF_PIXEL-2+0*FDEC_STRIDEB], 0
2264     pinsrw      %3, [r1+%2*SIZEOF_PIXEL-2+2*FDEC_STRIDEB], 2
2265     pinsrw      %3, [r1+%2*SIZEOF_PIXEL-2+3*FDEC_STRIDEB], 3
2266 %if HIGH_BIT_DEPTH == 0
2267     psrlw       %3, 8
2268 %endif
2269 %ifnidn %2, 0
2270     shr         %2d, 5
2271 %endif
2272 %endif ; direction
2273 %if cpuflag(ssse3)
2274     %define %%sign psignw
2275 %else
2276     %define %%sign pmullw
2277 %endif
2278     pshufw      %4, %3, q1032
2279     %%sign      %4, [pw_ppmmppmm]
2280     paddw       %3, %4
2281     pshufw      %4, %3, q2301
2282     %%sign      %4, [pw_pmpmpmpm]
2283     paddw       %3, %4
2284     psllw       %3, 2
2285     mova        [%1_1d+2*%2], %3
2286 %endmacro
2287
2288 %macro SUM_MM_X3 8 ; 3x sum, 4x tmp, op
2289     pxor        %7, %7
2290     pshufw      %4, %1, q1032
2291     pshufw      %5, %2, q1032
2292     pshufw      %6, %3, q1032
2293     paddw       %1, %4
2294     paddw       %2, %5
2295     paddw       %3, %6
2296     punpcklwd   %1, %7
2297     punpcklwd   %2, %7
2298     punpcklwd   %3, %7
2299     pshufw      %4, %1, q1032
2300     pshufw      %5, %2, q1032
2301     pshufw      %6, %3, q1032
2302     %8          %1, %4
2303     %8          %2, %5
2304     %8          %3, %6
2305 %endmacro
2306
2307 ; in: m1..m3
2308 ; out: m7
2309 ; clobber: m4..m6
2310 %macro SUM3x4 0
2311     ABSW2       m4, m5, m1, m2, m1, m2
2312     ABSW        m7, m3, m3
2313     paddw       m4, m5
2314     paddw       m7, m4
2315 %endmacro
2316
2317 ; in: m0..m3 (4x4)
2318 ; out: m0 v, m4 h, m5 dc
2319 ; clobber: m1..m3
2320 %macro SUM4x3 3 ; dc, left, top
2321     movq        m4, %2
2322 %ifid %1
2323     movq        m5, %1
2324 %else
2325     movd        m5, %1
2326 %endif
2327     psubw       m4, m0
2328     psubw       m5, m0
2329     punpcklwd   m0, m1
2330     punpcklwd   m2, m3
2331     punpckldq   m0, m2 ; transpose
2332     psubw       m0, %3
2333     ABSW2       m4, m5, m4, m5, m2, m3 ; 1x4 sum
2334     ABSW        m0, m0, m1 ; 4x1 sum
2335 %endmacro
2336
2337 %macro INTRA_X3_MMX 0
2338 ;-----------------------------------------------------------------------------
2339 ; void intra_satd_x3_4x4( uint8_t *fenc, uint8_t *fdec, int *res )
2340 ;-----------------------------------------------------------------------------
2341 cglobal intra_satd_x3_4x4, 3,3
2342 %if UNIX64
2343     ; stack is 16 byte aligned because abi says so
2344     %define  top_1d  rsp-8  ; size 8
2345     %define  left_1d rsp-16 ; size 8
2346 %else
2347     ; WIN64:  stack is 16 byte aligned because abi says so
2348     ; X86_32: stack is 16 byte aligned at least in gcc, and we've pushed 3 regs + return address, so it's still aligned
2349     SUB         rsp, 16
2350     %define  top_1d  rsp+8
2351     %define  left_1d rsp
2352 %endif
2353
2354     call hadamard_load
2355     SCALAR_HADAMARD left, 0, m4, m5
2356     SCALAR_HADAMARD top,  0, m6, m5, m7
2357     paddw       m6, m4
2358     pavgw       m6, [pw_16]
2359     pand        m6, [sw_f0] ; dc
2360
2361     SUM3x4
2362     SUM4x3 m6, [left_1d], [top_1d]
2363     paddw       m4, m7
2364     paddw       m5, m7
2365     movq        m1, m5
2366     psrlq       m1, 16  ; 4x3 sum
2367     paddw       m0, m1
2368
2369     SUM_MM_X3   m0, m4, m5, m1, m2, m3, m6, pavgw
2370     movd        [r2+0], m0 ; i4x4_v satd
2371     movd        [r2+4], m4 ; i4x4_h satd
2372     movd        [r2+8], m5 ; i4x4_dc satd
2373 %if UNIX64 == 0
2374     ADD         rsp, 16
2375 %endif
2376     RET
2377
2378 ;-----------------------------------------------------------------------------
2379 ; void intra_satd_x3_16x16( uint8_t *fenc, uint8_t *fdec, int *res )
2380 ;-----------------------------------------------------------------------------
2381 cglobal intra_satd_x3_16x16, 0,5
2382     %assign  stack_pad  120 + ((stack_offset+120+gprsize)&15)
2383     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
2384     SUB         rsp, stack_pad
2385 %define sums    rsp+64 ; size 56
2386 %define top_1d  rsp+32 ; size 32
2387 %define left_1d rsp    ; size 32
2388     movifnidn   r1,  r1mp
2389
2390     pxor        m7, m7
2391     mova [sums+ 0], m7
2392     mova [sums+ 8], m7
2393     mova [sums+16], m7
2394 %if HIGH_BIT_DEPTH
2395     mova [sums+24], m7
2396     mova [sums+32], m7
2397     mova [sums+40], m7
2398     mova [sums+48], m7
2399 %endif
2400
2401     ; 1D hadamards
2402     mov        r3d, 12
2403     movd        m6, [pw_32]
2404 .loop_edge:
2405     SCALAR_HADAMARD left, r3, m0, m1
2406     SCALAR_HADAMARD top,  r3, m1, m2, m3
2407     pavgw       m0, m1
2408     paddw       m6, m0
2409     sub        r3d, 4
2410     jge .loop_edge
2411     psrlw       m6, 2
2412     pand        m6, [sw_f0] ; dc
2413
2414     ; 2D hadamards
2415     movifnidn   r0, r0mp
2416     mov         r3, -4
2417 .loop_y:
2418     mov         r4, -4
2419 .loop_x:
2420     call hadamard_load
2421
2422     SUM3x4
2423     SUM4x3 m6, [left_1d+8*(r3+4)], [top_1d+8*(r4+4)]
2424     pavgw       m4, m7
2425     pavgw       m5, m7
2426     paddw       m0, [sums+ 0] ; i16x16_v satd
2427     paddw       m4, [sums+ 8] ; i16x16_h satd
2428     paddw       m5, [sums+16] ; i16x16_dc satd
2429     mova [sums+ 0], m0
2430     mova [sums+ 8], m4
2431     mova [sums+16], m5
2432
2433     add         r0, 4*SIZEOF_PIXEL
2434     inc         r4
2435     jl  .loop_x
2436 %if HIGH_BIT_DEPTH
2437     psrld       m7, m4, 16
2438     pslld       m4, 16
2439     psrld       m4, 16
2440     paddd       m4, m7
2441     psrld       m7, m0, 16
2442     pslld       m0, 16
2443     psrld       m0, 16
2444     paddd       m0, m7
2445     paddd       m4, [sums+32]
2446     paddd       m0, [sums+24]
2447     mova [sums+32], m4
2448     mova [sums+24], m0
2449     pxor        m7, m7
2450     punpckhwd   m3, m5, m7
2451     punpcklwd   m5, m7
2452     paddd       m3, [sums+48]
2453     paddd       m5, [sums+40]
2454     mova [sums+48], m3
2455     mova [sums+40], m5
2456     mova [sums+ 0], m7
2457     mova [sums+ 8], m7
2458     mova [sums+16], m7
2459 %endif
2460     add         r0, 4*FENC_STRIDEB-16*SIZEOF_PIXEL
2461     inc         r3
2462     jl  .loop_y
2463
2464 ; horizontal sum
2465     movifnidn   r2, r2mp
2466 %if HIGH_BIT_DEPTH
2467     mova        m1, m5
2468     paddd       m5, m3
2469     HADDD       m5, m7 ; DC satd
2470     HADDD       m4, m7 ; H satd
2471     HADDD       m0, m7 ; the part of V satd that doesn't overlap with DC
2472     psrld       m0, 1
2473     psrlq       m1, 32 ; DC[1]
2474     paddd       m0, m3 ; DC[2]
2475     psrlq       m3, 32 ; DC[3]
2476     paddd       m0, m1
2477     paddd       m0, m3
2478 %else
2479     mova        m7, m5
2480     SUM_MM_X3   m0, m4, m5, m3, m1, m2, m6, paddd
2481     psrld       m0, 1
2482     pslld       m7, 16
2483     psrld       m7, 16
2484     paddd       m0, m5
2485     psubd       m0, m7
2486 %endif
2487     movd    [r2+8], m5 ; i16x16_dc satd
2488     movd    [r2+4], m4 ; i16x16_h satd
2489     movd    [r2+0], m0 ; i16x16_v satd
2490     ADD        rsp, stack_pad
2491     RET
2492
2493 %if ARCH_X86_64
2494     %define  t0 r6
2495 %else
2496     %define  t0 r2
2497 %endif
2498
2499 ;-----------------------------------------------------------------------------
2500 ; void intra_satd_x3_8x8c( uint8_t *fenc, uint8_t *fdec, int *res )
2501 ;-----------------------------------------------------------------------------
2502 cglobal intra_satd_x3_8x8c, 0,6
2503     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
2504     SUB          rsp, 72
2505 %define  sums    rsp+48 ; size 24
2506 %define  dc_1d   rsp+32 ; size 16
2507 %define  top_1d  rsp+16 ; size 16
2508 %define  left_1d rsp    ; size 16
2509     movifnidn   r1,  r1mp
2510     pxor        m7, m7
2511     mova [sums+ 0], m7
2512     mova [sums+ 8], m7
2513     mova [sums+16], m7
2514
2515     ; 1D hadamards
2516     mov         r3d, 4
2517 .loop_edge:
2518     SCALAR_HADAMARD left, r3, m0, m1
2519     SCALAR_HADAMARD top,  r3, m0, m1, m2
2520     sub         r3d, 4
2521     jge .loop_edge
2522
2523     ; dc
2524     movzx       t0d, word [left_1d+0]
2525     movzx       r3d, word [top_1d+0]
2526     movzx       r4d, word [left_1d+8]
2527     movzx       r5d, word [top_1d+8]
2528     lea         t0d, [t0 + r3 + 16]
2529     lea         r3d, [r4 + r5 + 16]
2530     shr         t0d, 1
2531     shr         r3d, 1
2532     add         r4d, 8
2533     add         r5d, 8
2534     and         t0d, -16 ; tl
2535     and         r3d, -16 ; br
2536     and         r4d, -16 ; bl
2537     and         r5d, -16 ; tr
2538     mov         [dc_1d+ 0], t0d ; tl
2539     mov         [dc_1d+ 4], r5d ; tr
2540     mov         [dc_1d+ 8], r4d ; bl
2541     mov         [dc_1d+12], r3d ; br
2542     lea         r5, [dc_1d]
2543
2544     ; 2D hadamards
2545     movifnidn   r0,  r0mp
2546     movifnidn   r2,  r2mp
2547     mov         r3,  -2
2548 .loop_y:
2549     mov         r4,  -2
2550 .loop_x:
2551     call hadamard_load
2552
2553     SUM3x4
2554     SUM4x3 [r5+4*(r4+2)], [left_1d+8*(r3+2)], [top_1d+8*(r4+2)]
2555     pavgw       m4, m7
2556     pavgw       m5, m7
2557     paddw       m0, [sums+16] ; i4x4_v satd
2558     paddw       m4, [sums+8]  ; i4x4_h satd
2559     paddw       m5, [sums+0]  ; i4x4_dc satd
2560     movq        [sums+16], m0
2561     movq        [sums+8], m4
2562     movq        [sums+0], m5
2563
2564     add         r0, 4*SIZEOF_PIXEL
2565     inc         r4
2566     jl  .loop_x
2567     add         r0, 4*FENC_STRIDEB-8*SIZEOF_PIXEL
2568     add         r5, 8
2569     inc         r3
2570     jl  .loop_y
2571
2572 ; horizontal sum
2573     movq        m0, [sums+0]
2574     movq        m1, [sums+8]
2575     movq        m2, [sums+16]
2576     movq        m7, m0
2577 %if HIGH_BIT_DEPTH
2578     psrlq       m7, 16
2579     HADDW       m7, m3
2580     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
2581     psrld       m2, 1
2582     paddd       m2, m7
2583 %else
2584     psrlq       m7, 15
2585     paddw       m2, m7
2586     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
2587     psrld       m2, 1
2588 %endif
2589     movd        [r2+0], m0 ; i8x8c_dc satd
2590     movd        [r2+4], m1 ; i8x8c_h satd
2591     movd        [r2+8], m2 ; i8x8c_v satd
2592     ADD         rsp, 72
2593     RET
2594 %endmacro ; INTRA_X3_MMX
2595
2596
2597
2598 %macro PRED4x4_LOWPASS 5
2599 %ifid %5
2600     pavgb       %5, %2, %3
2601     pxor        %3, %2
2602     pand        %3, [pb_1]
2603     psubusb     %5, %3
2604     pavgb       %1, %4, %5
2605 %else
2606     mova        %5, %2
2607     pavgb       %2, %3
2608     pxor        %3, %5
2609     pand        %3, [pb_1]
2610     psubusb     %2, %3
2611     pavgb       %1, %4, %2
2612 %endif
2613 %endmacro
2614
2615 %macro INTRA_X9_PRED 2
2616 %if cpuflag(sse4)
2617     movu       m1, [r1-1*FDEC_STRIDE-8]
2618     pinsrb     m1, [r1+3*FDEC_STRIDE-1], 0
2619     pinsrb     m1, [r1+2*FDEC_STRIDE-1], 1
2620     pinsrb     m1, [r1+1*FDEC_STRIDE-1], 2
2621     pinsrb     m1, [r1+0*FDEC_STRIDE-1], 3
2622 %else
2623     movd      mm0, [r1+3*FDEC_STRIDE-4]
2624     punpcklbw mm0, [r1+2*FDEC_STRIDE-4]
2625     movd      mm1, [r1+1*FDEC_STRIDE-4]
2626     punpcklbw mm1, [r1+0*FDEC_STRIDE-4]
2627     punpckhwd mm0, mm1
2628     psrlq     mm0, 32
2629     movq2dq    m0, mm0
2630     movu       m1, [r1-1*FDEC_STRIDE-8]
2631     movss      m1, m0                  ; l3 l2 l1 l0 __ __ __ lt t0 t1 t2 t3 t4 t5 t6 t7
2632 %endif ; cpuflag
2633     pshufb     m1, [intrax9_edge]      ; l3 l3 l2 l1 l0 lt t0 t1 t2 t3 t4 t5 t6 t7 t7 __
2634     psrldq     m0, m1, 1               ; l3 l2 l1 l0 lt t0 t1 t2 t3 t4 t5 t6 t7 t7 __ __
2635     psrldq     m2, m1, 2               ; l2 l1 l0 lt t0 t1 t2 t3 t4 t5 t6 t7 t7 __ __ __
2636     pavgb      m5, m0, m1              ; Gl3 Gl2 Gl1 Gl0 Glt Gt0 Gt1 Gt2 Gt3 Gt4 Gt5  __  __ __ __ __
2637     mova       %2, m1
2638     PRED4x4_LOWPASS m0, m1, m2, m0, m4 ; Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 __ __ __
2639     ; ddl               ddr
2640     ; Ft1 Ft2 Ft3 Ft4   Flt Ft0 Ft1 Ft2
2641     ; Ft2 Ft3 Ft4 Ft5   Fl0 Flt Ft0 Ft1
2642     ; Ft3 Ft4 Ft5 Ft6   Fl1 Fl0 Flt Ft0
2643     ; Ft4 Ft5 Ft6 Ft7   Fl2 Fl1 Fl0 Flt
2644     pshufb     m2, m0, [%1_ddlr1] ; a: ddl row0, ddl row1, ddr row0, ddr row1 / b: ddl row0, ddr row0, ddl row1, ddr row1
2645     pshufb     m3, m0, [%1_ddlr2] ; rows 2,3
2646     ; hd                hu
2647     ; Glt Flt Ft0 Ft1   Gl0 Fl1 Gl1 Fl2
2648     ; Gl0 Fl0 Glt Flt   Gl1 Fl2 Gl2 Fl3
2649     ; Gl1 Fl1 Gl0 Fl0   Gl2 Fl3 Gl3 Gl3
2650     ; Gl2 Fl2 Gl1 Fl1   Gl3 Gl3 Gl3 Gl3
2651     pslldq     m0, 5                   ; ___ ___ ___ ___ ___ Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5
2652     palignr    m7, m5, m0, 5           ; Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Gl3 Gl2 Gl1 Gl0 Glt
2653     pshufb     m6, m7, [%1_hdu1]
2654     pshufb     m7, m7, [%1_hdu2]
2655     ; vr                vl
2656     ; Gt0 Gt1 Gt2 Gt3   Gt1 Gt2 Gt3 Gt4
2657     ; Flt Ft0 Ft1 Ft2   Ft1 Ft2 Ft3 Ft4
2658     ; Fl0 Gt0 Gt1 Gt2   Gt2 Gt3 Gt4 Gt5
2659     ; Fl1 Flt Ft0 Ft1   Ft2 Ft3 Ft4 Ft5
2660     psrldq     m5, 5                   ; Gt0 Gt1 Gt2 Gt3 Gt4 Gt5 ...
2661     palignr    m5, m0, 6               ; ___ Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Gt0 Gt1 Gt2 Gt3 Gt4 Gt5
2662     pshufb     m4, m5, [%1_vrl1]
2663     pshufb     m5, m5, [%1_vrl2]
2664 %endmacro ; INTRA_X9_PRED
2665
2666 %macro INTRA_X9_VHDC 5 ; edge, fenc01, fenc23, tmp, tmp
2667     pshufb     m2, m%1, [intrax9b_vh1]
2668     pshufb     m3, m%1, [intrax9b_vh2]
2669     mova      [pred_buf+0x60], m2
2670     mova      [pred_buf+0x70], m3
2671     pshufb    m%1, [intrax9b_edge2] ; t0 t1 t2 t3 t0 t1 t2 t3 l0 l1 l2 l3 l0 l1 l2 l3
2672     pmaddubsw m%1, [hmul_4p]
2673     pshufhw    m0, m%1, q2301
2674     pshuflw    m0, m0,  q2301
2675     psignw    m%1, [pw_pmpmpmpm]
2676     paddw      m0, m%1
2677     psllw      m0, 2 ; hadamard(top), hadamard(left)
2678     movhlps    m3, m0
2679     pshufb     m1, m0, [intrax9b_v1]
2680     pshufb     m2, m0, [intrax9b_v2]
2681     paddw      m0, m3
2682     psignw     m3, [pw_pmmpzzzz] ; FIXME could this be eliminated?
2683     pavgw      m0, [pw_16]
2684     pand       m0, [sw_f0] ; dc
2685     ; This (as well as one of the steps in intra_satd_x9_4x4.satd_8x4) could be
2686     ; changed from a wd transpose to a qdq, with appropriate rearrangement of inputs.
2687     ; Which would be faster on conroe, but slower on penryn and sandybridge, and too invasive to ifdef.
2688     HADAMARD 0, sumsub, %2, %3, %4, %5
2689     HADAMARD 1, sumsub, %2, %3, %4, %5
2690     movd      r3d, m0
2691     shr       r3d, 4
2692     imul      r3d, 0x01010101
2693     mov       [pred_buf+0x80], r3d
2694     mov       [pred_buf+0x88], r3d
2695     mov       [pred_buf+0x90], r3d
2696     mov       [pred_buf+0x98], r3d
2697     psubw      m3, m%2
2698     psubw      m0, m%2
2699     psubw      m1, m%2
2700     psubw      m2, m%3
2701     pabsw     m%3, m%3
2702     pabsw      m3, m3
2703     pabsw      m0, m0
2704     pabsw      m1, m1
2705     pabsw      m2, m2
2706     pavgw      m3, m%3
2707     pavgw      m0, m%3
2708     pavgw      m1, m2
2709 %if cpuflag(sse4)
2710     phaddw     m3, m0
2711 %else
2712     SBUTTERFLY qdq, 3, 0, 2
2713     paddw      m3, m0
2714 %endif
2715     movhlps    m2, m1
2716     paddw      m1, m2
2717 %if cpuflag(xop)
2718     vphaddwq   m3, m3
2719     vphaddwq   m1, m1
2720     packssdw   m1, m3
2721 %else
2722     phaddw     m1, m3
2723     pmaddwd    m1, [pw_1] ; v, _, h, dc
2724 %endif
2725 %endmacro ; INTRA_X9_VHDC
2726
2727 %macro INTRA_X9_END 2
2728 %if cpuflag(sse4)
2729     phminposuw m0, m0 ; h,dc,ddl,ddr,vr,hd,vl,hu
2730     movd      eax, m0
2731     add       eax, 1<<16
2732     cmp        ax, r3w
2733     cmovge    eax, r3d
2734 %else
2735 %if %1
2736     ; 4x4 sad is up to 12 bits; +bitcosts -> 13 bits; pack with 3 bit index
2737     psllw      m0, 3
2738     paddw      m0, [pw_s01234567] ; h,dc,ddl,ddr,vr,hd,vl,hu
2739 %else
2740     ; 4x4 satd is up to 13 bits; +bitcosts and saturate -> 13 bits; pack with 3 bit index
2741     psllw      m0, 2
2742     paddusw    m0, m0
2743     paddw      m0, [pw_s01234657] ; h,dc,ddl,ddr,vr,vl,hd,hu
2744 %endif
2745     movhlps    m1, m0
2746     pminsw     m0, m1
2747     pshuflw    m1, m0, q0032
2748     pminsw     m0, m1
2749     pshuflw    m1, m0, q0001
2750     pminsw     m0, m1
2751     movd      eax, m0
2752     movsx     r2d, ax
2753     and       eax, 7
2754     sar       r2d, 3
2755     shl       eax, 16
2756     ; 1<<16: increment index to match intra4x4_pred_e. couldn't do this before because it had to fit in 3 bits
2757     ; 1<<12: undo sign manipulation
2758     lea       eax, [rax+r2+(1<<16)+(1<<12)]
2759     cmp        ax, r3w
2760     cmovge    eax, r3d
2761 %endif ; cpuflag
2762
2763     ; output the predicted samples
2764     mov       r3d, eax
2765     shr       r3d, 16
2766 %ifdef PIC
2767     lea        r2, [%2_lut]
2768     movzx     r2d, byte [r2+r3]
2769 %else
2770     movzx     r2d, byte [%2_lut+r3]
2771 %endif
2772 %if %1 ; sad
2773     movq      mm0, [pred_buf+r2]
2774     movq      mm1, [pred_buf+r2+16]
2775     movd     [r1+0*FDEC_STRIDE], mm0
2776     movd     [r1+2*FDEC_STRIDE], mm1
2777     psrlq     mm0, 32
2778     psrlq     mm1, 32
2779     movd     [r1+1*FDEC_STRIDE], mm0
2780     movd     [r1+3*FDEC_STRIDE], mm1
2781 %else ; satd
2782 %assign i 0
2783 %rep 4
2784     mov       r3d, [pred_buf+r2+8*i]
2785     mov      [r1+i*FDEC_STRIDE], r3d
2786 %assign i i+1
2787 %endrep
2788 %endif
2789 %endmacro ; INTRA_X9_END
2790
2791 %macro INTRA_X9 0
2792 ;-----------------------------------------------------------------------------
2793 ; int intra_sad_x9_4x4( uint8_t *fenc, uint8_t *fdec, uint16_t *bitcosts )
2794 ;-----------------------------------------------------------------------------
2795 %if notcpuflag(xop)
2796 cglobal intra_sad_x9_4x4, 3,4,9
2797     %assign pad 0xc0-gprsize-(stack_offset&15)
2798     %define pred_buf rsp
2799     sub       rsp, pad
2800 %if ARCH_X86_64
2801     INTRA_X9_PRED intrax9a, m8
2802 %else
2803     INTRA_X9_PRED intrax9a, [rsp+0xa0]
2804 %endif
2805     mova [rsp+0x00], m2
2806     mova [rsp+0x10], m3
2807     mova [rsp+0x20], m4
2808     mova [rsp+0x30], m5
2809     mova [rsp+0x40], m6
2810     mova [rsp+0x50], m7
2811 %if cpuflag(sse4)
2812     movd       m0, [r0+0*FENC_STRIDE]
2813     pinsrd     m0, [r0+1*FENC_STRIDE], 1
2814     movd       m1, [r0+2*FENC_STRIDE]
2815     pinsrd     m1, [r0+3*FENC_STRIDE], 1
2816 %else
2817     movd      mm0, [r0+0*FENC_STRIDE]
2818     punpckldq mm0, [r0+1*FENC_STRIDE]
2819     movd      mm1, [r0+2*FENC_STRIDE]
2820     punpckldq mm1, [r0+3*FENC_STRIDE]
2821     movq2dq    m0, mm0
2822     movq2dq    m1, mm1
2823 %endif
2824     punpcklqdq m0, m0
2825     punpcklqdq m1, m1
2826     psadbw     m2, m0
2827     psadbw     m3, m1
2828     psadbw     m4, m0
2829     psadbw     m5, m1
2830     psadbw     m6, m0
2831     psadbw     m7, m1
2832     paddd      m2, m3
2833     paddd      m4, m5
2834     paddd      m6, m7
2835 %if ARCH_X86_64
2836     SWAP        7, 8
2837     pxor       m8, m8
2838     %define %%zero m8
2839 %else
2840     mova       m7, [rsp+0xa0]
2841     %define %%zero [pb_0]
2842 %endif
2843     pshufb     m3, m7, [intrax9a_vh1]
2844     pshufb     m5, m7, [intrax9a_vh2]
2845     pshufb     m7, [intrax9a_dc]
2846     psadbw     m7, %%zero
2847     psrlw      m7, 2
2848     mova [rsp+0x60], m3
2849     mova [rsp+0x70], m5
2850     psadbw     m3, m0
2851     pavgw      m7, %%zero
2852     pshufb     m7, %%zero
2853     psadbw     m5, m1
2854     movq [rsp+0x80], m7
2855     movq [rsp+0x90], m7
2856     psadbw     m0, m7
2857     paddd      m3, m5
2858     psadbw     m1, m7
2859     paddd      m0, m1
2860     movzx     r3d, word [r2]
2861     movd      r0d, m3 ; v
2862     add       r3d, r0d
2863     punpckhqdq m3, m0 ; h, dc
2864     shufps     m3, m2, q2020
2865     psllq      m6, 32
2866     por        m4, m6
2867     movu       m0, [r2+2]
2868     packssdw   m3, m4
2869     paddw      m0, m3
2870     INTRA_X9_END 1, intrax9a
2871     add       rsp, pad
2872     RET
2873 %endif ; cpuflag
2874
2875 %if ARCH_X86_64
2876 ;-----------------------------------------------------------------------------
2877 ; int intra_satd_x9_4x4( uint8_t *fenc, uint8_t *fdec, uint16_t *bitcosts )
2878 ;-----------------------------------------------------------------------------
2879 cglobal intra_satd_x9_4x4, 3,4,16
2880     %assign pad 0xb0-gprsize-(stack_offset&15)
2881     %define pred_buf rsp
2882     sub       rsp, pad
2883     INTRA_X9_PRED intrax9b, m15
2884     mova [rsp+0x00], m2
2885     mova [rsp+0x10], m3
2886     mova [rsp+0x20], m4
2887     mova [rsp+0x30], m5
2888     mova [rsp+0x40], m6
2889     mova [rsp+0x50], m7
2890     movd       m8, [r0+0*FENC_STRIDE]
2891     movd       m9, [r0+1*FENC_STRIDE]
2892     movd      m10, [r0+2*FENC_STRIDE]
2893     movd      m11, [r0+3*FENC_STRIDE]
2894     mova      m12, [hmul_8p]
2895     pshufd     m8, m8, 0
2896     pshufd     m9, m9, 0
2897     pshufd    m10, m10, 0
2898     pshufd    m11, m11, 0
2899     pmaddubsw  m8, m12
2900     pmaddubsw  m9, m12
2901     pmaddubsw m10, m12
2902     pmaddubsw m11, m12
2903     movddup    m0, m2
2904     pshufd     m1, m2, q3232
2905     movddup    m2, m3
2906     movhlps    m3, m3
2907     call .satd_8x4 ; ddr, ddl
2908     movddup    m2, m5
2909     pshufd     m3, m5, q3232
2910     mova       m5, m0
2911     movddup    m0, m4
2912     pshufd     m1, m4, q3232
2913     call .satd_8x4 ; vr, vl
2914     movddup    m2, m7
2915     pshufd     m3, m7, q3232
2916     mova       m4, m0
2917     movddup    m0, m6
2918     pshufd     m1, m6, q3232
2919     call .satd_8x4 ; hd, hu
2920 %if cpuflag(sse4)
2921     punpckldq  m4, m0
2922 %else
2923     punpcklqdq m4, m0 ; conroe dislikes punpckldq, and ssse3 INTRA_X9_END can handle arbitrary orders whereas phminposuw can't
2924 %endif
2925     mova       m1, [pw_ppmmppmm]
2926     psignw     m8, m1
2927     psignw    m10, m1
2928     paddw      m8, m9
2929     paddw     m10, m11
2930     INTRA_X9_VHDC 15, 8, 10, 6, 7
2931     ; find minimum
2932     movu       m0, [r2+2]
2933     movd      r3d, m1
2934     palignr    m5, m1, 8
2935 %if notcpuflag(sse4)
2936     pshufhw    m0, m0, q3120 ; compensate for different order in unpack
2937 %endif
2938     packssdw   m5, m4
2939     paddw      m0, m5
2940     movzx     r0d, word [r2]
2941     add       r3d, r0d
2942     INTRA_X9_END 0, intrax9b
2943     add       rsp, pad
2944     RET
2945 RESET_MM_PERMUTATION
2946 ALIGN 16
2947 .satd_8x4:
2948     pmaddubsw  m0, m12
2949     pmaddubsw  m1, m12
2950     pmaddubsw  m2, m12
2951     pmaddubsw  m3, m12
2952     psubw      m0, m8
2953     psubw      m1, m9
2954     psubw      m2, m10
2955     psubw      m3, m11
2956     SATD_8x4_SSE 0, 0, 1, 2, 3, 13, 14, 0, swap
2957     pmaddwd    m0, [pw_1]
2958 %if cpuflag(sse4)
2959     pshufd     m1, m0, q0032
2960 %else
2961     movhlps    m1, m0
2962 %endif
2963     paddd    xmm0, m0, m1 ; consistent location of return value. only the avx version of hadamard permutes m0, so 3arg is free
2964     ret
2965
2966 %else ; !ARCH_X86_64
2967 cglobal intra_satd_x9_4x4, 3,4,8
2968     %assign pad 0x120-gprsize-(stack_offset&15)
2969     %define fenc_buf rsp
2970     %define pred_buf rsp+0x40
2971     %define spill    rsp+0xe0
2972     sub       rsp, pad
2973     INTRA_X9_PRED intrax9b, [spill+0x20]
2974     mova [pred_buf+0x00], m2
2975     mova [pred_buf+0x10], m3
2976     mova [pred_buf+0x20], m4
2977     mova [pred_buf+0x30], m5
2978     mova [pred_buf+0x40], m6
2979     mova [pred_buf+0x50], m7
2980     movd       m4, [r0+0*FENC_STRIDE]
2981     movd       m5, [r0+1*FENC_STRIDE]
2982     movd       m6, [r0+2*FENC_STRIDE]
2983     movd       m0, [r0+3*FENC_STRIDE]
2984     mova       m7, [hmul_8p]
2985     pshufd     m4, m4, 0
2986     pshufd     m5, m5, 0
2987     pshufd     m6, m6, 0
2988     pshufd     m0, m0, 0
2989     pmaddubsw  m4, m7
2990     pmaddubsw  m5, m7
2991     pmaddubsw  m6, m7
2992     pmaddubsw  m0, m7
2993     mova [fenc_buf+0x00], m4
2994     mova [fenc_buf+0x10], m5
2995     mova [fenc_buf+0x20], m6
2996     mova [fenc_buf+0x30], m0
2997     movddup    m0, m2
2998     pshufd     m1, m2, q3232
2999     movddup    m2, m3
3000     movhlps    m3, m3
3001     pmaddubsw  m0, m7
3002     pmaddubsw  m1, m7
3003     pmaddubsw  m2, m7
3004     pmaddubsw  m3, m7
3005     psubw      m0, m4
3006     psubw      m1, m5
3007     psubw      m2, m6
3008     call .satd_8x4b ; ddr, ddl
3009     mova       m3, [pred_buf+0x30]
3010     mova       m1, [pred_buf+0x20]
3011     movddup    m2, m3
3012     movhlps    m3, m3
3013     movq [spill+0x08], m0
3014     movddup    m0, m1
3015     movhlps    m1, m1
3016     call .satd_8x4 ; vr, vl
3017     mova       m3, [pred_buf+0x50]
3018     mova       m1, [pred_buf+0x40]
3019     movddup    m2, m3
3020     movhlps    m3, m3
3021     movq [spill+0x10], m0
3022     movddup    m0, m1
3023     movhlps    m1, m1
3024     call .satd_8x4 ; hd, hu
3025     movq [spill+0x18], m0
3026     mova       m1, [spill+0x20]
3027     mova       m4, [fenc_buf+0x00]
3028     mova       m5, [fenc_buf+0x20]
3029     mova       m2, [pw_ppmmppmm]
3030     psignw     m4, m2
3031     psignw     m5, m2
3032     paddw      m4, [fenc_buf+0x10]
3033     paddw      m5, [fenc_buf+0x30]
3034     INTRA_X9_VHDC 1, 4, 5, 6, 7
3035     ; find minimum
3036     movu       m0, [r2+2]
3037     movd      r3d, m1
3038     punpckhqdq m1, [spill+0x00]
3039     packssdw   m1, [spill+0x10]
3040 %if cpuflag(sse4)
3041     pshufhw    m1, m1, q3120
3042 %else
3043     pshufhw    m0, m0, q3120
3044 %endif
3045     paddw      m0, m1
3046     movzx     r0d, word [r2]
3047     add       r3d, r0d
3048     INTRA_X9_END 0, intrax9b
3049     add       rsp, pad
3050     RET
3051 RESET_MM_PERMUTATION
3052 ALIGN 16
3053 .satd_8x4:
3054     pmaddubsw  m0, m7
3055     pmaddubsw  m1, m7
3056     pmaddubsw  m2, m7
3057     pmaddubsw  m3, m7
3058     %xdefine fenc_buf fenc_buf+gprsize
3059     psubw      m0, [fenc_buf+0x00]
3060     psubw      m1, [fenc_buf+0x10]
3061     psubw      m2, [fenc_buf+0x20]
3062 .satd_8x4b:
3063     psubw      m3, [fenc_buf+0x30]
3064     SATD_8x4_SSE 0, 0, 1, 2, 3, 4, 5, 0, swap
3065     pmaddwd    m0, [pw_1]
3066 %if cpuflag(sse4)
3067     pshufd     m1, m0, q0032
3068 %else
3069     movhlps    m1, m0
3070 %endif
3071     paddd    xmm0, m0, m1
3072     ret
3073 %endif ; ARCH
3074 %endmacro ; INTRA_X9
3075
3076
3077
3078 %macro INTRA8_X9 0
3079 ;-----------------------------------------------------------------------------
3080 ; int intra_sad_x9_8x8( uint8_t *fenc, uint8_t *fdec, uint8_t edge[36], uint16_t *bitcosts, uint16_t *satds )
3081 ;-----------------------------------------------------------------------------
3082 cglobal intra_sad_x9_8x8, 5,6,9
3083     %define fenc02 m4
3084     %define fenc13 m5
3085     %define fenc46 m6
3086     %define fenc57 m7
3087 %if ARCH_X86_64
3088     %define tmp m8
3089     %assign padbase 0x0
3090 %else
3091     %define tmp [rsp]
3092     %assign padbase 0x10
3093 %endif
3094     %assign pad 0x240+0x10+padbase-gprsize-(stack_offset&15)
3095     %define pred(i,j) [rsp+i*0x40+j*0x10+padbase]
3096
3097     SUB        rsp, pad
3098     movq    fenc02, [r0+FENC_STRIDE* 0]
3099     movq    fenc13, [r0+FENC_STRIDE* 1]
3100     movq    fenc46, [r0+FENC_STRIDE* 4]
3101     movq    fenc57, [r0+FENC_STRIDE* 5]
3102     movhps  fenc02, [r0+FENC_STRIDE* 2]
3103     movhps  fenc13, [r0+FENC_STRIDE* 3]
3104     movhps  fenc46, [r0+FENC_STRIDE* 6]
3105     movhps  fenc57, [r0+FENC_STRIDE* 7]
3106
3107     ; save instruction size: avoid 4-byte memory offsets
3108     lea         r0, [intra8x9_h1+128]
3109     %define off(m) (r0+m-(intra8x9_h1+128))
3110
3111 ; v
3112     movddup     m0, [r2+16]
3113     mova pred(0,0), m0
3114     psadbw      m1, m0, fenc02
3115     mova pred(0,1), m0
3116     psadbw      m2, m0, fenc13
3117     mova pred(0,2), m0
3118     psadbw      m3, m0, fenc46
3119     mova pred(0,3), m0
3120     psadbw      m0, m0, fenc57
3121     paddw       m1, m2
3122     paddw       m0, m3
3123     paddw       m0, m1
3124     movhlps     m1, m0
3125     paddw       m0, m1
3126     movd    [r4+0], m0
3127
3128 ; h
3129     movq        m0, [r2+7]
3130     pshufb      m1, m0, [off(intra8x9_h1)]
3131     pshufb      m2, m0, [off(intra8x9_h2)]
3132     mova pred(1,0), m1
3133     psadbw      m1, fenc02
3134     mova pred(1,1), m2
3135     psadbw      m2, fenc13
3136     paddw       m1, m2
3137     pshufb      m3, m0, [off(intra8x9_h3)]
3138     pshufb      m2, m0, [off(intra8x9_h4)]
3139     mova pred(1,2), m3
3140     psadbw      m3, fenc46
3141     mova pred(1,3), m2
3142     psadbw      m2, fenc57
3143     paddw       m1, m3
3144     paddw       m1, m2
3145     movhlps     m2, m1
3146     paddw       m1, m2
3147     movd    [r4+2], m1
3148
3149     lea         r5, [rsp+padbase+0x100]
3150     %define pred(i,j) [r5+i*0x40+j*0x10-0x100]
3151
3152 ; dc
3153     movhps      m0, [r2+16]
3154     pxor        m2, m2
3155     psadbw      m0, m2
3156     movhlps     m1, m0
3157     paddw       m0, m1
3158     psrlw       m0, 3
3159     pavgw       m0, m2
3160     pshufb      m0, m2
3161     mova pred(2,0), m0
3162     psadbw      m1, m0, fenc02
3163     mova pred(2,1), m0
3164     psadbw      m2, m0, fenc13
3165     mova pred(2,2), m0
3166     psadbw      m3, m0, fenc46
3167     mova pred(2,3), m0
3168     psadbw      m0, m0, fenc57
3169     paddw       m1, m2
3170     paddw       m0, m3
3171     paddw       m0, m1
3172     movhlps     m1, m0
3173     paddw       m0, m1
3174     movd    [r4+4], m0
3175
3176 ; ddl
3177 ; Ft1 Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 Ft8
3178 ; Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 Ft8 Ft9
3179 ; Ft3 Ft4 Ft5 Ft6 Ft7 Ft8 Ft9 FtA
3180 ; Ft4 Ft5 Ft6 Ft7 Ft8 Ft9 FtA FtB
3181 ; Ft5 Ft6 Ft7 Ft8 Ft9 FtA FtB FtC
3182 ; Ft6 Ft7 Ft8 Ft9 FtA FtB FtC FtD
3183 ; Ft7 Ft8 Ft9 FtA FtB FtC FtD FtE
3184 ; Ft8 Ft9 FtA FtB FtC FtD FtE FtF
3185     mova        m0, [r2+16]
3186     movu        m2, [r2+17]
3187     pslldq      m1, m0, 1
3188     pavgb       m3, m0, m2              ; Gt1 Gt2 Gt3 Gt4 Gt5 Gt6 Gt7 Gt8 Gt9 GtA GtB ___ ___ ___ ___ ___
3189     PRED4x4_LOWPASS m0, m1, m2, m0, tmp ; ___ Ft1 Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 Ft8 Ft9 FtA FtB FtC FtD FtE FtF
3190     pshufb      m1, m0, [off(intra8x9_ddl1)]
3191     pshufb      m2, m0, [off(intra8x9_ddl2)]
3192     mova pred(3,0), m1
3193     psadbw      m1, fenc02
3194     mova pred(3,1), m2
3195     psadbw      m2, fenc13
3196     paddw       m1, m2
3197     pshufb      m2, m0, [off(intra8x9_ddl3)]
3198     mova pred(3,2), m2
3199     psadbw      m2, fenc46
3200     paddw       m1, m2
3201     pshufb      m2, m0, [off(intra8x9_ddl4)]
3202     mova pred(3,3), m2
3203     psadbw      m2, fenc57
3204     paddw       m1, m2
3205     movhlps     m2, m1
3206     paddw       m1, m2
3207     movd    [r4+6], m1
3208
3209 ; vl
3210 ; Gt1 Gt2 Gt3 Gt4 Gt5 Gt6 Gt7 Gt8
3211 ; Ft1 Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 Ft8
3212 ; Gt2 Gt3 Gt4 Gt5 Gt6 Gt7 Gt8 Gt9
3213 ; Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 Ft8 Ft9
3214 ; Gt3 Gt4 Gt5 Gt6 Gt7 Gt8 Gt9 GtA
3215 ; Ft3 Ft4 Ft5 Ft6 Ft7 Ft8 Ft9 FtA
3216 ; Gt4 Gt5 Gt6 Gt7 Gt8 Gt9 GtA GtB
3217 ; Ft4 Ft5 Ft6 Ft7 Ft8 Ft9 FtA FtB
3218     pshufb      m1, m3, [off(intra8x9_vl1)]
3219     pshufb      m2, m0, [off(intra8x9_vl2)]
3220     pshufb      m3, m3, [off(intra8x9_vl3)]
3221     pshufb      m0, m0, [off(intra8x9_vl4)]
3222     mova pred(7,0), m1
3223     psadbw      m1, fenc02
3224     mova pred(7,1), m2
3225     psadbw      m2, fenc13
3226     mova pred(7,2), m3
3227     psadbw      m3, fenc46
3228     mova pred(7,3), m0
3229     psadbw      m0, fenc57
3230     paddw       m1, m2
3231     paddw       m0, m3
3232     paddw       m0, m1
3233     movhlps     m1, m0
3234     paddw       m0, m1
3235 %if cpuflag(sse4)
3236     pextrw [r4+14], m0, 0
3237 %else
3238     movd       r5d, m0
3239     mov    [r4+14], r5w
3240     lea         r5, [rsp+padbase+0x100]
3241 %endif
3242
3243 ; ddr
3244 ; Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Ft6
3245 ; Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5
3246 ; Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4
3247 ; Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3
3248 ; Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2
3249 ; Fl4 Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1
3250 ; Fl5 Fl4 Fl3 Fl2 Fl1 Fl0 Flt Ft0
3251 ; Fl6 Fl5 Fl4 Fl3 Fl2 Fl1 Fl0 Flt
3252     movu        m2, [r2+8]
3253     movu        m0, [r2+7]
3254     movu        m1, [r2+6]
3255     pavgb       m3, m2, m0              ; Gl6 Gl5 Gl4 Gl3 Gl2 Gl1 Gl0 Glt Gt0 Gt1 Gt2 Gt3 Gt4 Gt5 Gt6 Gt7
3256     PRED4x4_LOWPASS m0, m1, m2, m0, tmp ; Fl7 Fl6 Fl5 Fl4 Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Ft6
3257     pshufb      m1, m0, [off(intra8x9_ddr1)]
3258     pshufb      m2, m0, [off(intra8x9_ddr2)]
3259     mova pred(4,0), m1
3260     psadbw      m1, fenc02
3261     mova pred(4,1), m2
3262     psadbw      m2, fenc13
3263     paddw       m1, m2
3264     pshufb      m2, m0, [off(intra8x9_ddr3)]
3265     mova pred(4,2), m2
3266     psadbw      m2, fenc46
3267     paddw       m1, m2
3268     pshufb      m2, m0, [off(intra8x9_ddr4)]
3269     mova pred(4,3), m2
3270     psadbw      m2, fenc57
3271     paddw       m1, m2
3272     movhlps     m2, m1
3273     paddw       m1, m2
3274     movd    [r4+8], m1
3275
3276     add         r0, 256
3277     add         r5, 0xC0
3278     %define off(m) (r0+m-(intra8x9_h1+256+128))
3279     %define pred(i,j) [r5+i*0x40+j*0x10-0x1C0]
3280
3281 ; vr
3282 ; Gt0 Gt1 Gt2 Gt3 Gt4 Gt5 Gt6 Gt7
3283 ; Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Ft6
3284 ; Fl0 Gt0 Gt1 Gt2 Gt3 Gt4 Gt5 Gt6
3285 ; Fl1 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5
3286 ; Fl2 Fl0 Gt0 Gt1 Gt2 Gt3 Gt4 Gt5
3287 ; Fl3 Fl1 Flt Ft0 Ft1 Ft2 Ft3 Ft4
3288 ; Fl4 Fl2 Fl0 Gt0 Gt1 Gt2 Gt3 Gt4
3289 ; Fl5 Fl3 Fl1 Flt Ft0 Ft1 Ft2 Ft3
3290     movsd       m2, m3, m0 ; Fl7 Fl6 Fl5 Fl4 Fl3 Fl2 Fl1 Fl0 Gt0 Gt1 Gt2 Gt3 Gt4 Gt5 Gt6 Gt7
3291     pshufb      m1, m2, [off(intra8x9_vr1)]
3292     pshufb      m2, m2, [off(intra8x9_vr3)]
3293     mova pred(5,0), m1
3294     psadbw      m1, fenc02
3295     mova pred(5,2), m2
3296     psadbw      m2, fenc46
3297     paddw       m1, m2
3298     pshufb      m2, m0, [off(intra8x9_vr2)]
3299     mova pred(5,1), m2
3300     psadbw      m2, fenc13
3301     paddw       m1, m2
3302     pshufb      m2, m0, [off(intra8x9_vr4)]
3303     mova pred(5,3), m2
3304     psadbw      m2, fenc57
3305     paddw       m1, m2
3306     movhlps     m2, m1
3307     paddw       m1, m2
3308     movd   [r4+10], m1
3309
3310 ; hd
3311 ; Glt Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5
3312 ; Gl0 Fl0 Glt Flt Ft0 Ft1 Ft2 Ft3
3313 ; Gl1 Fl1 Gl0 Fl0 Glt Flt Ft0 Ft1
3314 ; Gl2 Fl2 Gl1 Fl1 Gl0 Fl0 Glt Flt
3315 ; Gl3 Fl3 Gl2 Fl2 Gl1 Fl1 Gl0 Fl0
3316 ; Gl4 Fl4 Gl3 Fl3 Gl2 Fl2 Gl1 Fl1
3317 ; Gl5 Fl5 Gl4 Fl4 Gl3 Fl3 Gl2 Fl2
3318 ; Gl6 Fl6 Gl5 Fl5 Gl4 Fl4 Gl3 Fl3
3319     pshufd      m2, m3, q0001
3320 %if cpuflag(sse4)
3321     pblendw     m2, m0, q3330 ; Gl2 Gl1 Gl0 Glt ___ Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 ___
3322 %else
3323     movss       m1, m0, m2
3324     SWAP        1, 2
3325 %endif
3326     punpcklbw   m0, m3        ; Fl7 Gl6 Fl6 Gl5 Fl5 Gl4 Fl4 Gl3 Fl3 Gl2 Fl2 Gl1 Fl1 Gl0 Fl0 ___
3327     pshufb      m1, m2, [off(intra8x9_hd1)]
3328     pshufb      m2, m2, [off(intra8x9_hd2)]
3329     mova pred(6,0), m1
3330     psadbw      m1, fenc02
3331     mova pred(6,1), m2
3332     psadbw      m2, fenc13
3333     paddw       m1, m2
3334     pshufb      m2, m0, [off(intra8x9_hd3)]
3335     pshufb      m3, m0, [off(intra8x9_hd4)]
3336     mova pred(6,2), m2
3337     psadbw      m2, fenc46
3338     mova pred(6,3), m3
3339     psadbw      m3, fenc57
3340     paddw       m1, m2
3341     paddw       m1, m3
3342     movhlps     m2, m1
3343     paddw       m1, m2
3344     ; don't just store to [r4+12]. this is too close to the load of dqword [r4] and would cause a forwarding stall
3345     pslldq      m1, 12
3346     SWAP        3, 1
3347
3348 ; hu
3349 ; Gl0 Fl1 Gl1 Fl2 Gl2 Fl3 Gl3 Fl4
3350 ; Gl1 Fl2 Gl2 Fl3 Gl3 Fl4 Gl4 Fl5
3351 ; Gl2 Fl3 Gl3 Gl3 Gl4 Fl5 Gl5 Fl6
3352 ; Gl3 Gl3 Gl4 Fl5 Gl5 Fl6 Gl6 Fl7
3353 ; Gl4 Fl5 Gl5 Fl6 Gl6 Fl7 Gl7 Gl7
3354 ; Gl5 Fl6 Gl6 Fl7 Gl7 Gl7 Gl7 Gl7
3355 ; Gl6 Fl7 Gl7 Gl7 Gl7 Gl7 Gl7 Gl7
3356 ; Gl7 Gl7 Gl7 Gl7 Gl7 Gl7 Gl7 Gl7
3357 %if cpuflag(sse4)
3358     pinsrb      m0, [r2+7], 15 ; Gl7
3359 %else
3360     movd        m1, [r2+7]
3361     pslldq      m0, 1
3362     palignr     m1, m0, 1
3363     SWAP        0, 1
3364 %endif
3365     pshufb      m1, m0, [off(intra8x9_hu1)]
3366     pshufb      m2, m0, [off(intra8x9_hu2)]
3367     mova pred(8,0), m1
3368     psadbw      m1, fenc02
3369     mova pred(8,1), m2
3370     psadbw      m2, fenc13
3371     paddw       m1, m2
3372     pshufb      m2, m0, [off(intra8x9_hu3)]
3373     pshufb      m0, m0, [off(intra8x9_hu4)]
3374     mova pred(8,2), m2
3375     psadbw      m2, fenc46
3376     mova pred(8,3), m0
3377     psadbw      m0, fenc57
3378     paddw       m1, m2
3379     paddw       m1, m0
3380     movhlps     m2, m1
3381     paddw       m1, m2
3382     movd       r2d, m1
3383
3384     movu        m0, [r3]
3385     por         m3, [r4]
3386     paddw       m0, m3
3387     mova      [r4], m0
3388     movzx      r5d, word [r3+16]
3389     add        r2d, r5d
3390     mov    [r4+16], r2w
3391
3392 %if cpuflag(sse4)
3393     phminposuw m0, m0 ; v,h,dc,ddl,ddr,vr,hd,vl
3394     movd      eax, m0
3395 %else
3396     ; 8x8 sad is up to 14 bits; +bitcosts and saturate -> 14 bits; pack with 2 bit index
3397     paddusw    m0, m0
3398     paddusw    m0, m0
3399     paddw      m0, [off(pw_s00112233)]
3400     movhlps    m1, m0
3401     pminsw     m0, m1
3402     pshuflw    m1, m0, q0032
3403     pminsw     m0, m1
3404     movd      eax, m0
3405     ; repack with 3 bit index
3406     xor       eax, 0x80008000
3407     movzx     r3d, ax
3408     shr       eax, 15
3409     add       r3d, r3d
3410     or        eax, 1
3411     cmp       eax, r3d
3412     cmovg     eax, r3d
3413     ; reverse to phminposuw order
3414     mov       r3d, eax
3415     and       eax, 7
3416     shr       r3d, 3
3417     shl       eax, 16
3418     or        eax, r3d
3419 %endif
3420     add       r2d, 8<<16
3421     cmp        ax, r2w
3422     cmovg     eax, r2d
3423
3424     mov       r2d, eax
3425     shr       r2d, 16
3426     shl       r2d, 6
3427     add        r1, 4*FDEC_STRIDE
3428     mova       m0, [rsp+padbase+r2+0x00]
3429     mova       m1, [rsp+padbase+r2+0x10]
3430     mova       m2, [rsp+padbase+r2+0x20]
3431     mova       m3, [rsp+padbase+r2+0x30]
3432     movq   [r1+FDEC_STRIDE*-4], m0
3433     movhps [r1+FDEC_STRIDE*-2], m0
3434     movq   [r1+FDEC_STRIDE*-3], m1
3435     movhps [r1+FDEC_STRIDE*-1], m1
3436     movq   [r1+FDEC_STRIDE* 0], m2
3437     movhps [r1+FDEC_STRIDE* 2], m2
3438     movq   [r1+FDEC_STRIDE* 1], m3
3439     movhps [r1+FDEC_STRIDE* 3], m3
3440     ADD       rsp, pad
3441     RET
3442
3443 %if ARCH_X86_64
3444 ;-----------------------------------------------------------------------------
3445 ; int intra_sa8d_x9_8x8( uint8_t *fenc, uint8_t *fdec, uint8_t edge[36], uint16_t *bitcosts, uint16_t *satds )
3446 ;-----------------------------------------------------------------------------
3447 cglobal intra_sa8d_x9_8x8, 5,6,16
3448     %assign pad 0x2c0+0x10-gprsize-(stack_offset&15)
3449     %define fenc_buf rsp
3450     %define pred_buf rsp+0x80
3451     SUB        rsp, pad
3452     mova       m15, [hmul_8p]
3453     pxor        m8, m8
3454 %assign %%i 0
3455 %rep 8
3456     movddup     m %+ %%i, [r0+%%i*FENC_STRIDE]
3457     pmaddubsw   m9, m %+ %%i, m15
3458     punpcklbw   m %+ %%i, m8
3459     mova [fenc_buf+%%i*0x10], m9
3460 %assign %%i %%i+1
3461 %endrep
3462
3463     ; save instruction size: avoid 4-byte memory offsets
3464     lea         r0, [intra8x9_h1+0x80]
3465     %define off(m) (r0+m-(intra8x9_h1+0x80))
3466     lea         r5, [pred_buf+0x80]
3467
3468 ; v, h, dc
3469     HADAMARD8_2D 0, 1, 2, 3, 4, 5, 6, 7, 8
3470     pabsw      m11, m1
3471 %assign %%i 2
3472 %rep 6
3473     pabsw       m8, m %+ %%i
3474     paddw      m11, m8
3475 %assign %%i %%i+1
3476 %endrep
3477
3478     ; 1D hadamard of edges
3479     movq        m8, [r2+7]
3480     movddup     m9, [r2+16]
3481     mova [r5-0x80], m9
3482     mova [r5-0x70], m9
3483     mova [r5-0x60], m9
3484     mova [r5-0x50], m9
3485     punpcklwd   m8, m8
3486     pshufb      m9, [intrax3_shuf]
3487     pmaddubsw   m8, [pb_pppm]
3488     pmaddubsw   m9, [pb_pppm]
3489     HSUMSUB2 psignw, m8, m9, m12, m13, m9, q1032, [pw_ppppmmmm]
3490     HSUMSUB2 psignw, m8, m9, m12, m13, m9, q2301, [pw_ppmmppmm]
3491
3492     ; dc
3493     paddw      m10, m8, m9
3494     paddw      m10, [pw_8]
3495     pand       m10, [sw_f0]
3496     psrlw      m12, m10, 4
3497     psllw      m10, 2
3498     pxor       m13, m13
3499     pshufb     m12, m13
3500     mova [r5+0x00], m12
3501     mova [r5+0x10], m12
3502     mova [r5+0x20], m12
3503     mova [r5+0x30], m12
3504
3505     ; differences
3506     psllw       m8, 3 ; left edge
3507     psubw       m8, m0
3508     psubw      m10, m0
3509     pabsw       m8, m8 ; 1x8 sum
3510     pabsw      m10, m10
3511     paddw       m8, m11
3512     paddw      m11, m10
3513     punpcklwd   m0, m1
3514     punpcklwd   m2, m3
3515     punpcklwd   m4, m5
3516     punpcklwd   m6, m7
3517     punpckldq   m0, m2
3518     punpckldq   m4, m6
3519     punpcklqdq  m0, m4 ; transpose
3520     psllw       m9, 3  ; top edge
3521     psrldq     m10, m11, 2 ; 8x7 sum
3522     psubw       m0, m9 ; 8x1 sum
3523     pabsw       m0, m0
3524     paddw      m10, m0
3525
3526     phaddd     m10, m8 ; logically phaddw, but this is faster and it won't overflow
3527     psrlw      m11, 1
3528     psrlw      m10, 1
3529
3530 ; store h
3531     movq        m3, [r2+7]
3532     pshufb      m0, m3, [off(intra8x9_h1)]
3533     pshufb      m1, m3, [off(intra8x9_h2)]
3534     pshufb      m2, m3, [off(intra8x9_h3)]
3535     pshufb      m3, m3, [off(intra8x9_h4)]
3536     mova [r5-0x40], m0
3537     mova [r5-0x30], m1
3538     mova [r5-0x20], m2
3539     mova [r5-0x10], m3
3540
3541 ; ddl
3542     mova        m8, [r2+16]
3543     movu        m2, [r2+17]
3544     pslldq      m1, m8, 1
3545     pavgb       m9, m8, m2
3546     PRED4x4_LOWPASS m8, m1, m2, m8, m3
3547     pshufb      m0, m8, [off(intra8x9_ddl1)]
3548     pshufb      m1, m8, [off(intra8x9_ddl2)]
3549     pshufb      m2, m8, [off(intra8x9_ddl3)]
3550     pshufb      m3, m8, [off(intra8x9_ddl4)]
3551     add         r5, 0x40
3552     call .sa8d
3553     phaddd     m11, m0
3554
3555 ; vl
3556     pshufb      m0, m9, [off(intra8x9_vl1)]
3557     pshufb      m1, m8, [off(intra8x9_vl2)]
3558     pshufb      m2, m9, [off(intra8x9_vl3)]
3559     pshufb      m3, m8, [off(intra8x9_vl4)]
3560     add         r5, 0x100
3561     call .sa8d
3562     phaddd     m10, m11
3563     mova       m12, m0
3564
3565 ; ddr
3566     movu        m2, [r2+8]
3567     movu        m8, [r2+7]
3568     movu        m1, [r2+6]
3569     pavgb       m9, m2, m8
3570     PRED4x4_LOWPASS m8, m1, m2, m8, m3
3571     pshufb      m0, m8, [off(intra8x9_ddr1)]
3572     pshufb      m1, m8, [off(intra8x9_ddr2)]
3573     pshufb      m2, m8, [off(intra8x9_ddr3)]
3574     pshufb      m3, m8, [off(intra8x9_ddr4)]
3575     sub         r5, 0xc0
3576     call .sa8d
3577     mova       m11, m0
3578
3579     add         r0, 0x100
3580     %define off(m) (r0+m-(intra8x9_h1+0x180))
3581
3582 ; vr
3583     movsd       m2, m9, m8
3584     pshufb      m0, m2, [off(intra8x9_vr1)]
3585     pshufb      m1, m8, [off(intra8x9_vr2)]
3586     pshufb      m2, m2, [off(intra8x9_vr3)]
3587     pshufb      m3, m8, [off(intra8x9_vr4)]
3588     add         r5, 0x40
3589     call .sa8d
3590     phaddd     m11, m0
3591
3592 ; hd
3593 %if cpuflag(sse4)
3594     pshufd      m1, m9, q0001
3595     pblendw     m1, m8, q3330
3596 %else
3597     pshufd      m2, m9, q0001
3598     movss       m1, m8, m2
3599 %endif
3600     punpcklbw   m8, m9
3601     pshufb      m0, m1, [off(intra8x9_hd1)]
3602     pshufb      m1, m1, [off(intra8x9_hd2)]
3603     pshufb      m2, m8, [off(intra8x9_hd3)]
3604     pshufb      m3, m8, [off(intra8x9_hd4)]
3605     add         r5, 0x40
3606     call .sa8d
3607     phaddd      m0, m12
3608     phaddd     m11, m0
3609
3610 ; hu
3611 %if cpuflag(sse4)
3612     pinsrb      m8, [r2+7], 15
3613 %else
3614     movd        m9, [r2+7]
3615     pslldq      m8, 1
3616     palignr     m9, m8, 1
3617     SWAP        8, 9
3618 %endif
3619     pshufb      m0, m8, [off(intra8x9_hu1)]
3620     pshufb      m1, m8, [off(intra8x9_hu2)]
3621     pshufb      m2, m8, [off(intra8x9_hu3)]
3622     pshufb      m3, m8, [off(intra8x9_hu4)]
3623     add         r5, 0x80
3624     call .sa8d
3625
3626     pmaddwd     m0, [pw_1]
3627     phaddw     m10, m11
3628     movhlps     m1, m0
3629     paddw       m0, m1
3630     pshuflw     m1, m0, q0032
3631     pavgw       m0, m1
3632     pxor        m2, m2
3633     pavgw      m10, m2
3634     movd       r2d, m0
3635
3636     movu        m0, [r3]
3637     paddw       m0, m10
3638     mova      [r4], m0
3639     movzx      r5d, word [r3+16]
3640     add        r2d, r5d
3641     mov    [r4+16], r2w
3642
3643 %if cpuflag(sse4)
3644     phminposuw m0, m0
3645     movd      eax, m0
3646 %else
3647     ; 8x8 sa8d is up to 15 bits; +bitcosts and saturate -> 15 bits; pack with 1 bit index
3648     paddusw    m0, m0
3649     paddw      m0, [off(pw_s00001111)]
3650     movhlps    m1, m0
3651     pminsw     m0, m1
3652     pshuflw    m1, m0, q0032
3653     mova       m2, m0
3654     pminsw     m0, m1
3655     pcmpgtw    m2, m1 ; 2nd index bit
3656     movd      r3d, m0
3657     movd      r4d, m2
3658     ; repack with 3 bit index
3659     xor       r3d, 0x80008000
3660     and       r4d, 0x00020002
3661     movzx     eax, r3w
3662     movzx     r5d, r4w
3663     shr       r3d, 16
3664     shr       r4d, 16
3665     lea       eax, [rax*4+r5]
3666     lea       r3d, [ r3*4+r4+1]
3667     cmp       eax, r3d
3668     cmovg     eax, r3d
3669     ; reverse to phminposuw order
3670     mov       r3d, eax
3671     and       eax, 7
3672     shr       r3d, 3
3673     shl       eax, 16
3674     or        eax, r3d
3675 %endif
3676     add       r2d, 8<<16
3677     cmp        ax, r2w
3678     cmovg     eax, r2d
3679
3680     mov       r2d, eax
3681     shr       r2d, 16
3682     shl       r2d, 6
3683     add        r1, 4*FDEC_STRIDE
3684     mova       m0, [pred_buf+r2+0x00]
3685     mova       m1, [pred_buf+r2+0x10]
3686     mova       m2, [pred_buf+r2+0x20]
3687     mova       m3, [pred_buf+r2+0x30]
3688     movq   [r1+FDEC_STRIDE*-4], m0
3689     movhps [r1+FDEC_STRIDE*-2], m0
3690     movq   [r1+FDEC_STRIDE*-3], m1
3691     movhps [r1+FDEC_STRIDE*-1], m1
3692     movq   [r1+FDEC_STRIDE* 0], m2
3693     movhps [r1+FDEC_STRIDE* 2], m2
3694     movq   [r1+FDEC_STRIDE* 1], m3
3695     movhps [r1+FDEC_STRIDE* 3], m3
3696     ADD       rsp, pad
3697     RET
3698
3699 ALIGN 16
3700 .sa8d:
3701     %xdefine mret m0
3702     %xdefine fenc_buf fenc_buf+gprsize
3703     mova [r5+0x00], m0
3704     mova [r5+0x10], m1
3705     mova [r5+0x20], m2
3706     mova [r5+0x30], m3
3707     movddup     m4, m0
3708     movddup     m5, m1
3709     movddup     m6, m2
3710     movddup     m7, m3
3711     punpckhqdq  m0, m0
3712     punpckhqdq  m1, m1
3713     punpckhqdq  m2, m2
3714     punpckhqdq  m3, m3
3715     PERMUTE 0,4, 1,5, 2,0, 3,1, 4,6, 5,7, 6,2, 7,3
3716     pmaddubsw   m0, m15
3717     pmaddubsw   m1, m15
3718     psubw       m0, [fenc_buf+0x00]
3719     psubw       m1, [fenc_buf+0x10]
3720     pmaddubsw   m2, m15
3721     pmaddubsw   m3, m15
3722     psubw       m2, [fenc_buf+0x20]
3723     psubw       m3, [fenc_buf+0x30]
3724     pmaddubsw   m4, m15
3725     pmaddubsw   m5, m15
3726     psubw       m4, [fenc_buf+0x40]
3727     psubw       m5, [fenc_buf+0x50]
3728     pmaddubsw   m6, m15
3729     pmaddubsw   m7, m15
3730     psubw       m6, [fenc_buf+0x60]
3731     psubw       m7, [fenc_buf+0x70]
3732     HADAMARD8_2D_HMUL 0, 1, 2, 3, 4, 5, 6, 7, 13, 14
3733     paddw       m0, m1
3734     paddw       m0, m2
3735     paddw mret, m0, m3
3736     ret
3737 %endif ; ARCH_X86_64
3738 %endmacro ; INTRA8_X9
3739
3740 ; in:  r0=pix, r1=stride, r2=stride*3, r3=tmp, m6=mask_ac4, m7=0
3741 ; out: [tmp]=hadamard4, m0=satd
3742 INIT_MMX mmx2
3743 cglobal hadamard_ac_4x4
3744 %if HIGH_BIT_DEPTH
3745     mova      m0, [r0]
3746     mova      m1, [r0+r1]
3747     mova      m2, [r0+r1*2]
3748     mova      m3, [r0+r2]
3749 %else ; !HIGH_BIT_DEPTH
3750     movh      m0, [r0]
3751     movh      m1, [r0+r1]
3752     movh      m2, [r0+r1*2]
3753     movh      m3, [r0+r2]
3754     punpcklbw m0, m7
3755     punpcklbw m1, m7
3756     punpcklbw m2, m7
3757     punpcklbw m3, m7
3758 %endif ; HIGH_BIT_DEPTH
3759     HADAMARD4_2D 0, 1, 2, 3, 4
3760     mova [r3],    m0
3761     mova [r3+8],  m1
3762     mova [r3+16], m2
3763     mova [r3+24], m3
3764     ABSW      m0, m0, m4
3765     ABSW      m1, m1, m4
3766     pand      m0, m6
3767     ABSW      m2, m2, m4
3768     ABSW      m3, m3, m4
3769     paddw     m0, m1
3770     paddw     m2, m3
3771     paddw     m0, m2
3772     SAVE_MM_PERMUTATION
3773     ret
3774
3775 cglobal hadamard_ac_2x2max
3776     mova      m0, [r3+0x00]
3777     mova      m1, [r3+0x20]
3778     mova      m2, [r3+0x40]
3779     mova      m3, [r3+0x60]
3780     sub       r3, 8
3781     SUMSUB_BADC w, 0, 1, 2, 3, 4
3782     ABSW2 m0, m2, m0, m2, m4, m5
3783     ABSW2 m1, m3, m1, m3, m4, m5
3784     HADAMARD 0, max, 0, 2, 4, 5
3785     HADAMARD 0, max, 1, 3, 4, 5
3786 %if HIGH_BIT_DEPTH
3787     pmaddwd   m0, m7
3788     pmaddwd   m1, m7
3789     paddd     m6, m0
3790     paddd     m6, m1
3791 %else ; !HIGH_BIT_DEPTH
3792     paddw     m7, m0
3793     paddw     m7, m1
3794 %endif ; HIGH_BIT_DEPTH
3795     SAVE_MM_PERMUTATION
3796     ret
3797
3798 %macro AC_PREP 2
3799 %if HIGH_BIT_DEPTH
3800     pmaddwd %1, %2
3801 %endif
3802 %endmacro
3803
3804 %macro AC_PADD 3
3805 %if HIGH_BIT_DEPTH
3806     AC_PREP %2, %3
3807     paddd   %1, %2
3808 %else
3809     paddw   %1, %2
3810 %endif ; HIGH_BIT_DEPTH
3811 %endmacro
3812
3813 cglobal hadamard_ac_8x8
3814     mova      m6, [mask_ac4]
3815 %if HIGH_BIT_DEPTH
3816     mova      m7, [pw_1]
3817 %else
3818     pxor      m7, m7
3819 %endif ; HIGH_BIT_DEPTH
3820     call hadamard_ac_4x4_mmx2
3821     add       r0, 4*SIZEOF_PIXEL
3822     add       r3, 32
3823     mova      m5, m0
3824     AC_PREP   m5, m7
3825     call hadamard_ac_4x4_mmx2
3826     lea       r0, [r0+4*r1]
3827     add       r3, 64
3828     AC_PADD   m5, m0, m7
3829     call hadamard_ac_4x4_mmx2
3830     sub       r0, 4*SIZEOF_PIXEL
3831     sub       r3, 32
3832     AC_PADD   m5, m0, m7
3833     call hadamard_ac_4x4_mmx2
3834     AC_PADD   m5, m0, m7
3835     sub       r3, 40
3836     mova [rsp+gprsize+8], m5 ; save satd
3837 %if HIGH_BIT_DEPTH
3838     pxor      m6, m6
3839 %endif
3840 %rep 3
3841     call hadamard_ac_2x2max_mmx2
3842 %endrep
3843     mova      m0, [r3+0x00]
3844     mova      m1, [r3+0x20]
3845     mova      m2, [r3+0x40]
3846     mova      m3, [r3+0x60]
3847     SUMSUB_BADC w, 0, 1, 2, 3, 4
3848     HADAMARD 0, sumsub, 0, 2, 4, 5
3849     ABSW2 m1, m3, m1, m3, m4, m5
3850     ABSW2 m0, m2, m0, m2, m4, m5
3851     HADAMARD 0, max, 1, 3, 4, 5
3852 %if HIGH_BIT_DEPTH
3853     pand      m0, [mask_ac4]
3854     pmaddwd   m1, m7
3855     pmaddwd   m0, m7
3856     pmaddwd   m2, m7
3857     paddd     m6, m1
3858     paddd     m0, m2
3859     paddd     m6, m6
3860     paddd     m0, m6
3861     SWAP       0,  6
3862 %else ; !HIGH_BIT_DEPTH
3863     pand      m6, m0
3864     paddw     m7, m1
3865     paddw     m6, m2
3866     paddw     m7, m7
3867     paddw     m6, m7
3868 %endif ; HIGH_BIT_DEPTH
3869     mova [rsp+gprsize], m6 ; save sa8d
3870     SWAP       0,  6
3871     SAVE_MM_PERMUTATION
3872     ret
3873
3874 %macro HADAMARD_AC_WXH_SUM_MMX 2
3875     mova    m1, [rsp+1*mmsize]
3876 %if HIGH_BIT_DEPTH
3877 %if %1*%2 >= 128
3878     paddd   m0, [rsp+2*mmsize]
3879     paddd   m1, [rsp+3*mmsize]
3880 %endif
3881 %if %1*%2 == 256
3882     mova    m2, [rsp+4*mmsize]
3883     paddd   m1, [rsp+5*mmsize]
3884     paddd   m2, [rsp+6*mmsize]
3885     mova    m3, m0
3886     paddd   m1, [rsp+7*mmsize]
3887     paddd   m0, m2
3888 %endif
3889     psrld   m0, 1
3890     HADDD   m0, m2
3891     psrld   m1, 1
3892     HADDD   m1, m3
3893 %else ; !HIGH_BIT_DEPTH
3894 %if %1*%2 >= 128
3895     paddusw m0, [rsp+2*mmsize]
3896     paddusw m1, [rsp+3*mmsize]
3897 %endif
3898 %if %1*%2 == 256
3899     mova    m2, [rsp+4*mmsize]
3900     paddusw m1, [rsp+5*mmsize]
3901     paddusw m2, [rsp+6*mmsize]
3902     mova    m3, m0
3903     paddusw m1, [rsp+7*mmsize]
3904     pxor    m3, m2
3905     pand    m3, [pw_1]
3906     pavgw   m0, m2
3907     psubusw m0, m3
3908     HADDUW  m0, m2
3909 %else
3910     psrlw   m0, 1
3911     HADDW   m0, m2
3912 %endif
3913     psrlw   m1, 1
3914     HADDW   m1, m3
3915 %endif ; HIGH_BIT_DEPTH
3916 %endmacro
3917
3918 %macro HADAMARD_AC_WXH_MMX 2
3919 cglobal pixel_hadamard_ac_%1x%2, 2,4
3920     %assign pad 16-gprsize-(stack_offset&15)
3921     %define ysub r1
3922     FIX_STRIDES r1
3923     sub  rsp, 16+128+pad
3924     lea  r2, [r1*3]
3925     lea  r3, [rsp+16]
3926     call hadamard_ac_8x8_mmx2
3927 %if %2==16
3928     %define ysub r2
3929     lea  r0, [r0+r1*4]
3930     sub  rsp, 16
3931     call hadamard_ac_8x8_mmx2
3932 %endif
3933 %if %1==16
3934     neg  ysub
3935     sub  rsp, 16
3936     lea  r0, [r0+ysub*4+8*SIZEOF_PIXEL]
3937     neg  ysub
3938     call hadamard_ac_8x8_mmx2
3939 %if %2==16
3940     lea  r0, [r0+r1*4]
3941     sub  rsp, 16
3942     call hadamard_ac_8x8_mmx2
3943 %endif
3944 %endif
3945     HADAMARD_AC_WXH_SUM_MMX %1, %2
3946     movd edx, m0
3947     movd eax, m1
3948     shr  edx, 1
3949 %if ARCH_X86_64
3950     shl  rdx, 32
3951     add  rax, rdx
3952 %endif
3953     add  rsp, 128+%1*%2/4+pad
3954     RET
3955 %endmacro ; HADAMARD_AC_WXH_MMX
3956
3957 HADAMARD_AC_WXH_MMX 16, 16
3958 HADAMARD_AC_WXH_MMX  8, 16
3959 HADAMARD_AC_WXH_MMX 16,  8
3960 HADAMARD_AC_WXH_MMX  8,  8
3961
3962 %macro LOAD_INC_8x4W_SSE2 5
3963 %if HIGH_BIT_DEPTH
3964     movu      m%1, [r0]
3965     movu      m%2, [r0+r1]
3966     movu      m%3, [r0+r1*2]
3967     movu      m%4, [r0+r2]
3968 %ifidn %1, 0
3969     lea       r0, [r0+r1*4]
3970 %endif
3971 %else ; !HIGH_BIT_DEPTH
3972     movh      m%1, [r0]
3973     movh      m%2, [r0+r1]
3974     movh      m%3, [r0+r1*2]
3975     movh      m%4, [r0+r2]
3976 %ifidn %1, 0
3977     lea       r0, [r0+r1*4]
3978 %endif
3979     punpcklbw m%1, m%5
3980     punpcklbw m%2, m%5
3981     punpcklbw m%3, m%5
3982     punpcklbw m%4, m%5
3983 %endif ; HIGH_BIT_DEPTH
3984 %endmacro
3985
3986 %macro LOAD_INC_8x4W_SSSE3 5
3987     LOAD_DUP_4x8P %3, %4, %1, %2, [r0+r1*2], [r0+r2], [r0], [r0+r1]
3988 %ifidn %1, 0
3989     lea       r0, [r0+r1*4]
3990 %endif
3991     HSUMSUB %1, %2, %3, %4, %5
3992 %endmacro
3993
3994 %macro HADAMARD_AC_SSE2 0
3995 ; in:  r0=pix, r1=stride, r2=stride*3
3996 ; out: [esp+16]=sa8d, [esp+32]=satd, r0+=stride*4
3997 cglobal hadamard_ac_8x8
3998 %if ARCH_X86_64
3999     %define spill0 m8
4000     %define spill1 m9
4001     %define spill2 m10
4002 %else
4003     %define spill0 [rsp+gprsize]
4004     %define spill1 [rsp+gprsize+mmsize]
4005     %define spill2 [rsp+gprsize+mmsize*2]
4006 %endif
4007 %if HIGH_BIT_DEPTH
4008     %define vertical 1
4009 %elif cpuflag(ssse3) && notcpuflag(atom)
4010     %define vertical 0
4011     ;LOAD_INC loads sumsubs
4012     mova      m7, [hmul_8p]
4013 %else
4014     %define vertical 1
4015     ;LOAD_INC only unpacks to words
4016     pxor      m7, m7
4017 %endif
4018     LOAD_INC_8x4W 0, 1, 2, 3, 7
4019 %if vertical
4020     HADAMARD4_2D_SSE 0, 1, 2, 3, 4
4021 %else
4022     HADAMARD4_V 0, 1, 2, 3, 4
4023 %endif
4024     mova  spill0, m1
4025     SWAP 1, 7
4026     LOAD_INC_8x4W 4, 5, 6, 7, 1
4027 %if vertical
4028     HADAMARD4_2D_SSE 4, 5, 6, 7, 1
4029 %else
4030     HADAMARD4_V 4, 5, 6, 7, 1
4031     ; FIXME SWAP
4032     mova      m1, spill0
4033     mova      spill0, m6
4034     mova      spill1, m7
4035     HADAMARD 1, sumsub, 0, 1, 6, 7
4036     HADAMARD 1, sumsub, 2, 3, 6, 7
4037     mova      m6, spill0
4038     mova      m7, spill1
4039     mova      spill0, m1
4040     mova      spill1, m0
4041     HADAMARD 1, sumsub, 4, 5, 1, 0
4042     HADAMARD 1, sumsub, 6, 7, 1, 0
4043     mova      m0, spill1
4044 %endif
4045     mova  spill1, m2
4046     mova  spill2, m3
4047     ABSW      m1, m0, m0
4048     ABSW      m2, m4, m4
4049     ABSW      m3, m5, m5
4050     paddw     m1, m2
4051     SUMSUB_BA w, 0, 4
4052 %if vertical
4053     pand      m1, [mask_ac4]
4054 %else
4055     pand      m1, [mask_ac4b]
4056 %endif
4057     AC_PREP   m1, [pw_1]
4058     ABSW      m2, spill0
4059     AC_PADD   m1, m3, [pw_1]
4060     ABSW      m3, spill1
4061     AC_PADD   m1, m2, [pw_1]
4062     ABSW      m2, spill2
4063     AC_PADD   m1, m3, [pw_1]
4064     ABSW      m3, m6, m6
4065     AC_PADD   m1, m2, [pw_1]
4066     ABSW      m2, m7, m7
4067     AC_PADD   m1, m3, [pw_1]
4068     AC_PADD   m1, m2, [pw_1]
4069     paddw     m3, m7, spill2
4070     psubw     m7, spill2
4071     mova  [rsp+gprsize+mmsize*2], m1 ; save satd
4072     paddw     m2, m6, spill1
4073     psubw     m6, spill1
4074     paddw     m1, m5, spill0
4075     psubw     m5, spill0
4076     %assign %%x 2
4077 %if vertical
4078     %assign %%x 4
4079 %endif
4080     mova  spill1, m4
4081     HADAMARD %%x, amax, 3, 7, 4
4082     HADAMARD %%x, amax, 2, 6, 7, 4
4083     mova      m4, spill1
4084     HADAMARD %%x, amax, 1, 5, 6, 7
4085     HADAMARD %%x, sumsub, 0, 4, 5, 6
4086     AC_PREP   m2, [pw_1]
4087     AC_PADD   m2, m3, [pw_1]
4088     AC_PADD   m2, m1, [pw_1]
4089 %if HIGH_BIT_DEPTH
4090     paddd     m2, m2
4091 %else
4092     paddw     m2, m2
4093 %endif ; HIGH_BIT_DEPTH
4094     ABSW      m4, m4, m7
4095     pand      m0, [mask_ac8]
4096     ABSW      m0, m0, m7
4097     AC_PADD   m2, m4, [pw_1]
4098     AC_PADD   m2, m0, [pw_1]
4099     mova [rsp+gprsize+mmsize], m2 ; save sa8d
4100     SWAP       0, 2
4101     SAVE_MM_PERMUTATION
4102     ret
4103
4104 HADAMARD_AC_WXH_SSE2 16, 16
4105 HADAMARD_AC_WXH_SSE2 16,  8
4106 %if mmsize <= 16
4107 HADAMARD_AC_WXH_SSE2  8, 16
4108 HADAMARD_AC_WXH_SSE2  8,  8
4109 %endif
4110 %endmacro ; HADAMARD_AC_SSE2
4111
4112 %macro HADAMARD_AC_WXH_SUM_SSE2 2
4113     mova    m1, [rsp+2*mmsize]
4114 %if HIGH_BIT_DEPTH
4115 %if %1*%2 >= 128
4116     paddd   m0, [rsp+3*mmsize]
4117     paddd   m1, [rsp+4*mmsize]
4118 %endif
4119 %if %1*%2 == 256
4120     paddd   m0, [rsp+5*mmsize]
4121     paddd   m1, [rsp+6*mmsize]
4122     paddd   m0, [rsp+7*mmsize]
4123     paddd   m1, [rsp+8*mmsize]
4124     psrld   m0, 1
4125 %endif
4126     HADDD  xm0, xm2
4127     HADDD  xm1, xm3
4128 %else ; !HIGH_BIT_DEPTH
4129 %if %1*%2*16/mmsize >= 128
4130     paddusw m0, [rsp+3*mmsize]
4131     paddusw m1, [rsp+4*mmsize]
4132 %endif
4133 %if %1*%2*16/mmsize == 256
4134     paddusw m0, [rsp+5*mmsize]
4135     paddusw m1, [rsp+6*mmsize]
4136     paddusw m0, [rsp+7*mmsize]
4137     paddusw m1, [rsp+8*mmsize]
4138     psrlw   m0, 1
4139 %endif
4140 %if mmsize==32
4141     vextracti128 xm2, m0, 1
4142     vextracti128 xm3, m1, 1
4143     paddusw xm0, xm2
4144     paddusw xm1, xm3
4145 %endif
4146     HADDUW xm0, xm2
4147     HADDW  xm1, xm3
4148 %endif ; HIGH_BIT_DEPTH
4149 %endmacro
4150
4151 ; struct { int satd, int sa8d; } pixel_hadamard_ac_16x16( uint8_t *pix, int stride )
4152 %macro HADAMARD_AC_WXH_SSE2 2
4153 cglobal pixel_hadamard_ac_%1x%2, 2,4,11
4154     %define ysub r1
4155     FIX_STRIDES r1
4156     mov   r3, rsp
4157     and  rsp, ~(mmsize-1)
4158     sub  rsp, mmsize*3
4159     lea   r2, [r1*3]
4160     call hadamard_ac_8x8
4161 %if %2==16
4162     %define ysub r2
4163     lea   r0, [r0+r1*4]
4164     sub  rsp, mmsize*2
4165     call hadamard_ac_8x8
4166 %endif
4167 %if %1==16 && mmsize <= 16
4168     neg  ysub
4169     sub  rsp, mmsize*2
4170     lea   r0, [r0+ysub*4+8*SIZEOF_PIXEL]
4171     neg  ysub
4172     call hadamard_ac_8x8
4173 %if %2==16
4174     lea   r0, [r0+r1*4]
4175     sub  rsp, mmsize*2
4176     call hadamard_ac_8x8
4177 %endif
4178 %endif
4179     HADAMARD_AC_WXH_SUM_SSE2 %1, %2
4180     movd edx, xm0
4181     movd eax, xm1
4182     shr  edx, 2 - (%1*%2*16/mmsize >> 8)
4183     shr  eax, 1
4184 %if ARCH_X86_64
4185     shl  rdx, 32
4186     add  rax, rdx
4187 %endif
4188     mov  rsp, r3
4189     RET
4190 %endmacro ; HADAMARD_AC_WXH_SSE2
4191
4192 ; instantiate satds
4193
4194 %if ARCH_X86_64 == 0
4195 cextern pixel_sa8d_8x8_internal_mmx2
4196 INIT_MMX mmx2
4197 SA8D
4198 %endif
4199
4200 %define TRANS TRANS_SSE2
4201 %define DIFFOP DIFF_UNPACK_SSE2
4202 %define LOAD_INC_8x4W LOAD_INC_8x4W_SSE2
4203 %define LOAD_SUMSUB_8x4P LOAD_DIFF_8x4P
4204 %define LOAD_SUMSUB_16P  LOAD_SUMSUB_16P_SSE2
4205 %define movdqa movaps ; doesn't hurt pre-nehalem, might as well save size
4206 %define movdqu movups
4207 %define punpcklqdq movlhps
4208 INIT_XMM sse2
4209 SA8D
4210 SATDS_SSE2
4211 %if ARCH_X86_64
4212 SA8D_SATD
4213 %endif
4214 %if HIGH_BIT_DEPTH == 0
4215 INTRA_SA8D_SSE2
4216 %endif
4217 INIT_MMX mmx2
4218 INTRA_X3_MMX
4219 INIT_XMM sse2
4220 HADAMARD_AC_SSE2
4221
4222 %if HIGH_BIT_DEPTH == 0
4223 INIT_XMM ssse3,atom
4224 SATDS_SSE2
4225 SA8D
4226 HADAMARD_AC_SSE2
4227 %if ARCH_X86_64
4228 SA8D_SATD
4229 %endif
4230 %endif
4231
4232 %define DIFFOP DIFF_SUMSUB_SSSE3
4233 %define LOAD_DUP_4x8P LOAD_DUP_4x8P_CONROE
4234 %if HIGH_BIT_DEPTH == 0
4235 %define LOAD_INC_8x4W LOAD_INC_8x4W_SSSE3
4236 %define LOAD_SUMSUB_8x4P LOAD_SUMSUB_8x4P_SSSE3
4237 %define LOAD_SUMSUB_16P  LOAD_SUMSUB_16P_SSSE3
4238 %endif
4239 INIT_XMM ssse3
4240 SATDS_SSE2
4241 SA8D
4242 HADAMARD_AC_SSE2
4243 %if ARCH_X86_64
4244 SA8D_SATD
4245 %endif
4246 %if HIGH_BIT_DEPTH == 0
4247 INTRA_X9
4248 INTRA8_X9
4249 %endif
4250 %undef movdqa ; nehalem doesn't like movaps
4251 %undef movdqu ; movups
4252 %undef punpcklqdq ; or movlhps
4253 %if HIGH_BIT_DEPTH == 0
4254 INIT_MMX ssse3
4255 INTRA_X3_MMX
4256 %endif
4257
4258 %define TRANS TRANS_SSE4
4259 %define LOAD_DUP_4x8P LOAD_DUP_4x8P_PENRYN
4260 INIT_XMM sse4
4261 SATDS_SSE2
4262 SA8D
4263 HADAMARD_AC_SSE2
4264 %if ARCH_X86_64
4265 SA8D_SATD
4266 %endif
4267 %if HIGH_BIT_DEPTH == 0
4268 INTRA_X9
4269 INTRA8_X9
4270 %endif
4271
4272 ; Sandy/Ivy Bridge and Bulldozer do movddup in the load unit, so
4273 ; it's effectively free.
4274 %define LOAD_DUP_4x8P LOAD_DUP_4x8P_CONROE
4275 INIT_XMM avx
4276 SATDS_SSE2
4277 SA8D
4278 %if ARCH_X86_64
4279 SA8D_SATD
4280 %endif
4281 %if HIGH_BIT_DEPTH == 0
4282 INTRA_X9
4283 INTRA8_X9
4284 %endif
4285 HADAMARD_AC_SSE2
4286
4287 %define TRANS TRANS_XOP
4288 INIT_XMM xop
4289 SATDS_SSE2
4290 SA8D
4291 %if ARCH_X86_64
4292 SA8D_SATD
4293 %endif
4294 %if HIGH_BIT_DEPTH == 0
4295 INTRA_X9
4296 ; no xop INTRA8_X9. it's slower than avx on bulldozer. dunno why.
4297 %endif
4298 HADAMARD_AC_SSE2
4299
4300
4301 %if HIGH_BIT_DEPTH == 0
4302 %define LOAD_SUMSUB_8x4P LOAD_SUMSUB8_16x4P_AVX2
4303 %define LOAD_DUP_4x8P LOAD_DUP_4x16P_AVX2
4304 %define TRANS TRANS_SSE4
4305 INIT_YMM avx2
4306 HADAMARD_AC_SSE2
4307 %if ARCH_X86_64
4308 SA8D_SATD
4309 %endif
4310
4311 %macro LOAD_SUMSUB_8x8P_AVX2 7 ; 4*dst, 2*tmp, mul]
4312     movq   xm%1, [r0]
4313     movq   xm%3, [r2]
4314     movq   xm%2, [r0+r1]
4315     movq   xm%4, [r2+r3]
4316     vinserti128 m%1, m%1, [r0+4*r1], 1
4317     vinserti128 m%3, m%3, [r2+4*r3], 1
4318     vinserti128 m%2, m%2, [r0+r4], 1
4319     vinserti128 m%4, m%4, [r2+r5], 1
4320     punpcklqdq m%1, m%1
4321     punpcklqdq m%3, m%3
4322     punpcklqdq m%2, m%2
4323     punpcklqdq m%4, m%4
4324     DIFF_SUMSUB_SSSE3 %1, %3, %2, %4, %7
4325     lea      r0, [r0+2*r1]
4326     lea      r2, [r2+2*r3]
4327
4328     movq   xm%3, [r0]
4329     movq   xm%5, [r2]
4330     movq   xm%4, [r0+r1]
4331     movq   xm%6, [r2+r3]
4332     vinserti128 m%3, m%3, [r0+4*r1], 1
4333     vinserti128 m%5, m%5, [r2+4*r3], 1
4334     vinserti128 m%4, m%4, [r0+r4], 1
4335     vinserti128 m%6, m%6, [r2+r5], 1
4336     punpcklqdq m%3, m%3
4337     punpcklqdq m%5, m%5
4338     punpcklqdq m%4, m%4
4339     punpcklqdq m%6, m%6
4340     DIFF_SUMSUB_SSSE3 %3, %5, %4, %6, %7
4341 %endmacro
4342
4343 %macro SATD_START_AVX2 2-3 0
4344     FIX_STRIDES r1, r3
4345 %if %3
4346     mova    %2, [hmul_8p]
4347     lea     r4, [5*r1]
4348     lea     r5, [5*r3]
4349 %else
4350     mova    %2, [hmul_16p]
4351     lea     r4, [3*r1]
4352     lea     r5, [3*r3]
4353 %endif
4354     pxor    %1, %1
4355 %endmacro
4356
4357 %define TRANS TRANS_SSE4
4358 INIT_YMM avx2
4359 cglobal pixel_satd_16x8_internal
4360     LOAD_SUMSUB_16x4P_AVX2 0, 1, 2, 3, 4, 5, 7, r0, r2, 1
4361     SATD_8x4_SSE 0, 0, 1, 2, 3, 4, 5, 6
4362     LOAD_SUMSUB_16x4P_AVX2 0, 1, 2, 3, 4, 5, 7, r0, r2, 0
4363     SATD_8x4_SSE 0, 0, 1, 2, 3, 4, 5, 6
4364     ret
4365
4366 cglobal pixel_satd_16x16, 4,6,8
4367     SATD_START_AVX2 m6, m7
4368     call pixel_satd_16x8_internal
4369     lea  r0, [r0+4*r1]
4370     lea  r2, [r2+4*r3]
4371 pixel_satd_16x8_internal:
4372     call pixel_satd_16x8_internal
4373     vextracti128 xm0, m6, 1
4374     paddw        xm0, xm6
4375     SATD_END_SSE2 xm0
4376     RET
4377
4378 cglobal pixel_satd_16x8, 4,6,8
4379     SATD_START_AVX2 m6, m7
4380     jmp pixel_satd_16x8_internal
4381
4382 cglobal pixel_satd_8x8_internal
4383     LOAD_SUMSUB_8x8P_AVX2 0, 1, 2, 3, 4, 5, 7
4384     SATD_8x4_SSE 0, 0, 1, 2, 3, 4, 5, 6
4385     ret
4386
4387 cglobal pixel_satd_8x16, 4,6,8
4388     SATD_START_AVX2 m6, m7, 1
4389     call pixel_satd_8x8_internal
4390     lea  r0, [r0+2*r1]
4391     lea  r2, [r2+2*r3]
4392     lea  r0, [r0+4*r1]
4393     lea  r2, [r2+4*r3]
4394     call pixel_satd_8x8_internal
4395     vextracti128 xm0, m6, 1
4396     paddw        xm0, xm6
4397     SATD_END_SSE2 xm0
4398     RET
4399
4400 cglobal pixel_satd_8x8, 4,6,8
4401     SATD_START_AVX2 m6, m7, 1
4402     call pixel_satd_8x8_internal
4403     vextracti128 xm0, m6, 1
4404     paddw        xm0, xm6
4405     SATD_END_SSE2 xm0
4406     RET
4407
4408 cglobal pixel_sa8d_8x8_internal
4409     LOAD_SUMSUB_8x8P_AVX2 0, 1, 2, 3, 4, 5, 7
4410     HADAMARD4_V 0, 1, 2, 3, 4
4411     HADAMARD 8, sumsub, 0, 1, 4, 5
4412     HADAMARD 8, sumsub, 2, 3, 4, 5
4413     HADAMARD 2, sumsub, 0, 1, 4, 5
4414     HADAMARD 2, sumsub, 2, 3, 4, 5
4415     HADAMARD 1, amax, 0, 1, 4, 5
4416     HADAMARD 1, amax, 2, 3, 4, 5
4417     paddw  m6, m0
4418     paddw  m6, m2
4419     ret
4420
4421 cglobal pixel_sa8d_8x8, 4,6,8
4422     SATD_START_AVX2 m6, m7, 1
4423     call pixel_sa8d_8x8_internal
4424     vextracti128 xm1, m6, 1
4425     paddw xm6, xm1
4426     HADDW xm6, xm1
4427     movd  eax, xm6
4428     add   eax, 1
4429     shr   eax, 1
4430     RET
4431
4432 cglobal intra_sad_x9_8x8, 5,7,8
4433     %define pred(i,j) [rsp+i*0x40+j*0x20]
4434
4435     mov         r6, rsp
4436     and        rsp, ~31
4437     sub        rsp, 0x240
4438     movu        m5, [r0+0*FENC_STRIDE]
4439     movu        m6, [r0+4*FENC_STRIDE]
4440     punpcklqdq  m5, [r0+2*FENC_STRIDE]
4441     punpcklqdq  m6, [r0+6*FENC_STRIDE]
4442
4443     ; save instruction size: avoid 4-byte memory offsets
4444     lea         r0, [intra8x9_h1+128]
4445     %define off(m) (r0+m-(intra8x9_h1+128))
4446
4447     vpbroadcastq m0, [r2+16]
4448     psadbw      m4, m0, m5
4449     psadbw      m2, m0, m6
4450     mova pred(0,0), m0
4451     mova pred(0,1), m0
4452     paddw       m4, m2
4453
4454     vpbroadcastq m1, [r2+7]
4455     pshufb      m3, m1, [off(intra8x9_h1)]
4456     pshufb      m2, m1, [off(intra8x9_h3)]
4457     mova pred(1,0), m3
4458     mova pred(1,1), m2
4459     psadbw      m3, m5
4460     psadbw      m2, m6
4461     paddw       m3, m2
4462
4463     lea         r5, [rsp+0x100]
4464     %define pred(i,j) [r5+i*0x40+j*0x20-0x100]
4465
4466     ; combine the first two
4467     pslldq      m3, 2
4468     por         m4, m3
4469
4470     pxor        m2, m2
4471     psadbw      m0, m2
4472     psadbw      m1, m2
4473     paddw       m0, m1
4474     psrlw       m0, 3
4475     pavgw       m0, m2
4476     pshufb      m0, m2
4477     mova pred(2,0), m0
4478     mova pred(2,1), m0
4479     psadbw      m3, m0, m5
4480     psadbw      m2, m0, m6
4481     paddw       m3, m2
4482
4483     pslldq      m3, 4
4484     por         m4, m3
4485
4486     vbroadcasti128 m0, [r2+16]
4487     vbroadcasti128 m2, [r2+17]
4488     pslldq      m1, m0, 1
4489     pavgb       m3, m0, m2
4490     PRED4x4_LOWPASS m0, m1, m2, m0, m7
4491     pshufb      m1, m0, [off(intra8x9_ddl1)]
4492     pshufb      m2, m0, [off(intra8x9_ddl3)]
4493     mova pred(3,0), m1
4494     mova pred(3,1), m2
4495     psadbw      m1, m5
4496     psadbw      m2, m6
4497     paddw       m1, m2
4498
4499     pslldq      m1, 6
4500     por         m4, m1
4501     vextracti128 xm1, m4, 1
4502     paddw      xm4, xm1
4503     mova      [r4], xm4
4504
4505     ; for later
4506     vinserti128 m7, m3, xm0, 1
4507
4508     vbroadcasti128 m2, [r2+8]
4509     vbroadcasti128 m0, [r2+7]
4510     vbroadcasti128 m1, [r2+6]
4511     pavgb       m3, m2, m0
4512     PRED4x4_LOWPASS m0, m1, m2, m0, m4
4513     pshufb      m1, m0, [off(intra8x9_ddr1)]
4514     pshufb      m2, m0, [off(intra8x9_ddr3)]
4515     mova pred(4,0), m1
4516     mova pred(4,1), m2
4517     psadbw      m4, m1, m5
4518     psadbw      m2, m6
4519     paddw       m4, m2
4520
4521     add         r0, 256
4522     add         r5, 0xC0
4523     %define off(m) (r0+m-(intra8x9_h1+256+128))
4524     %define pred(i,j) [r5+i*0x40+j*0x20-0x1C0]
4525
4526     vpblendd    m2, m3, m0, 11110011b
4527     pshufb      m1, m2, [off(intra8x9_vr1)]
4528     pshufb      m2, m2, [off(intra8x9_vr3)]
4529     mova pred(5,0), m1
4530     mova pred(5,1), m2
4531     psadbw      m1, m5
4532     psadbw      m2, m6
4533     paddw       m1, m2
4534
4535     pslldq      m1, 2
4536     por         m4, m1
4537
4538     psrldq      m2, m3, 4
4539     pblendw     m2, m0, q3330
4540     punpcklbw   m0, m3
4541     pshufb      m1, m2, [off(intra8x9_hd1)]
4542     pshufb      m2, m0, [off(intra8x9_hd3)]
4543     mova pred(6,0), m1
4544     mova pred(6,1), m2
4545     psadbw      m1, m5
4546     psadbw      m2, m6
4547     paddw       m1, m2
4548
4549     pslldq      m1, 4
4550     por         m4, m1
4551
4552     pshufb      m1, m7, [off(intra8x9_vl1)]
4553     pshufb      m2, m7, [off(intra8x9_vl3)]
4554     mova pred(7,0), m1
4555     mova pred(7,1), m2
4556     psadbw      m1, m5
4557     psadbw      m2, m6
4558     paddw       m1, m2
4559
4560     pslldq      m1, 6
4561     por         m4, m1
4562     vextracti128 xm1, m4, 1
4563     paddw      xm4, xm1
4564     mova       xm3, [r4]
4565     SBUTTERFLY qdq, 3, 4, 7
4566     paddw      xm3, xm4
4567
4568     pslldq      m1, m0, 1
4569     vpbroadcastd m0, [r2+7]
4570     palignr     m0, m1, 1
4571     pshufb      m1, m0, [off(intra8x9_hu1)]
4572     pshufb      m2, m0, [off(intra8x9_hu3)]
4573     mova pred(8,0), m1
4574     mova pred(8,1), m2
4575     psadbw      m1, m5
4576     psadbw      m2, m6
4577     paddw       m1, m2
4578     vextracti128 xm2, m1, 1
4579     paddw      xm1, xm2
4580     movhlps    xm2, xm1
4581     paddw      xm1, xm2
4582     movd       r2d, xm1
4583
4584     paddw      xm3, [r3]
4585     mova      [r4], xm3
4586     add        r2w, word [r3+16]
4587     mov    [r4+16], r2w
4588
4589     phminposuw xm3, xm3
4590     movd       r3d, xm3
4591     add        r2d, 8<<16
4592     cmp        r3w, r2w
4593     cmovg      r3d, r2d
4594
4595     mov        r2d, r3d
4596     shr         r3, 16
4597     shl         r3, 6
4598     add         r1, 4*FDEC_STRIDE
4599     mova       xm0, [rsp+r3+0x00]
4600     mova       xm1, [rsp+r3+0x10]
4601     mova       xm2, [rsp+r3+0x20]
4602     mova       xm3, [rsp+r3+0x30]
4603     movq   [r1+FDEC_STRIDE*-4], xm0
4604     movhps [r1+FDEC_STRIDE*-2], xm0
4605     movq   [r1+FDEC_STRIDE*-3], xm1
4606     movhps [r1+FDEC_STRIDE*-1], xm1
4607     movq   [r1+FDEC_STRIDE* 0], xm2
4608     movhps [r1+FDEC_STRIDE* 2], xm2
4609     movq   [r1+FDEC_STRIDE* 1], xm3
4610     movhps [r1+FDEC_STRIDE* 3], xm3
4611     mov        rsp, r6
4612     mov        eax, r2d
4613     RET
4614 %endif ; HIGH_BIT_DEPTH
4615
4616 ;=============================================================================
4617 ; SSIM
4618 ;=============================================================================
4619
4620 ;-----------------------------------------------------------------------------
4621 ; void pixel_ssim_4x4x2_core( const uint8_t *pix1, intptr_t stride1,
4622 ;                             const uint8_t *pix2, intptr_t stride2, int sums[2][4] )
4623 ;-----------------------------------------------------------------------------
4624 %macro SSIM_ITER 1
4625 %if HIGH_BIT_DEPTH
4626     movdqu    m5, [r0+(%1&1)*r1]
4627     movdqu    m6, [r2+(%1&1)*r3]
4628 %else
4629     movq      m5, [r0+(%1&1)*r1]
4630     movq      m6, [r2+(%1&1)*r3]
4631     punpcklbw m5, m0
4632     punpcklbw m6, m0
4633 %endif
4634 %if %1==1
4635     lea       r0, [r0+r1*2]
4636     lea       r2, [r2+r3*2]
4637 %endif
4638 %if %1==0
4639     movdqa    m1, m5
4640     movdqa    m2, m6
4641 %else
4642     paddw     m1, m5
4643     paddw     m2, m6
4644 %endif
4645     pmaddwd   m7, m5, m6
4646     pmaddwd   m5, m5
4647     pmaddwd   m6, m6
4648     ACCUM  paddd, 3, 5, %1
4649     ACCUM  paddd, 4, 7, %1
4650     paddd     m3, m6
4651 %endmacro
4652
4653 %macro SSIM 0
4654 cglobal pixel_ssim_4x4x2_core, 4,4,8
4655     FIX_STRIDES r1, r3
4656     pxor      m0, m0
4657     SSIM_ITER 0
4658     SSIM_ITER 1
4659     SSIM_ITER 2
4660     SSIM_ITER 3
4661     ; PHADDW m1, m2
4662     ; PHADDD m3, m4
4663     movdqa    m7, [pw_1]
4664     pshufd    m5, m3, q2301
4665     pmaddwd   m1, m7
4666     pmaddwd   m2, m7
4667     pshufd    m6, m4, q2301
4668     packssdw  m1, m2
4669     paddd     m3, m5
4670     pshufd    m1, m1, q3120
4671     paddd     m4, m6
4672     pmaddwd   m1, m7
4673     punpckhdq m5, m3, m4
4674     punpckldq m3, m4
4675
4676 %if UNIX64
4677     %define t0 r4
4678 %else
4679     %define t0 rax
4680     mov t0, r4mp
4681 %endif
4682
4683     movq      [t0+ 0], m1
4684     movq      [t0+ 8], m3
4685     movhps    [t0+16], m1
4686     movq      [t0+24], m5
4687     RET
4688
4689 ;-----------------------------------------------------------------------------
4690 ; float pixel_ssim_end( int sum0[5][4], int sum1[5][4], int width )
4691 ;-----------------------------------------------------------------------------
4692 cglobal pixel_ssim_end4, 3,3,7
4693     movdqa    m0, [r0+ 0]
4694     movdqa    m1, [r0+16]
4695     movdqa    m2, [r0+32]
4696     movdqa    m3, [r0+48]
4697     movdqa    m4, [r0+64]
4698     paddd     m0, [r1+ 0]
4699     paddd     m1, [r1+16]
4700     paddd     m2, [r1+32]
4701     paddd     m3, [r1+48]
4702     paddd     m4, [r1+64]
4703     paddd     m0, m1
4704     paddd     m1, m2
4705     paddd     m2, m3
4706     paddd     m3, m4
4707     movdqa    m5, [ssim_c1]
4708     movdqa    m6, [ssim_c2]
4709     TRANSPOSE4x4D  0, 1, 2, 3, 4
4710
4711 ;   s1=m0, s2=m1, ss=m2, s12=m3
4712 %if BIT_DEPTH == 10
4713     cvtdq2ps  m0, m0
4714     cvtdq2ps  m1, m1
4715     cvtdq2ps  m2, m2
4716     cvtdq2ps  m3, m3
4717     mulps     m2, [pf_64] ; ss*64
4718     mulps     m3, [pf_128] ; s12*128
4719     movdqa    m4, m1
4720     mulps     m4, m0      ; s1*s2
4721     mulps     m1, m1      ; s2*s2
4722     mulps     m0, m0      ; s1*s1
4723     addps     m4, m4      ; s1*s2*2
4724     addps     m0, m1      ; s1*s1 + s2*s2
4725     subps     m2, m0      ; vars
4726     subps     m3, m4      ; covar*2
4727     addps     m4, m5      ; s1*s2*2 + ssim_c1
4728     addps     m0, m5      ; s1*s1 + s2*s2 + ssim_c1
4729     addps     m2, m6      ; vars + ssim_c2
4730     addps     m3, m6      ; covar*2 + ssim_c2
4731 %else
4732     pmaddwd   m4, m1, m0  ; s1*s2
4733     pslld     m1, 16
4734     por       m0, m1
4735     pmaddwd   m0, m0  ; s1*s1 + s2*s2
4736     pslld     m4, 1
4737     pslld     m3, 7
4738     pslld     m2, 6
4739     psubd     m3, m4  ; covar*2
4740     psubd     m2, m0  ; vars
4741     paddd     m0, m5
4742     paddd     m4, m5
4743     paddd     m3, m6
4744     paddd     m2, m6
4745     cvtdq2ps  m0, m0  ; (float)(s1*s1 + s2*s2 + ssim_c1)
4746     cvtdq2ps  m4, m4  ; (float)(s1*s2*2 + ssim_c1)
4747     cvtdq2ps  m3, m3  ; (float)(covar*2 + ssim_c2)
4748     cvtdq2ps  m2, m2  ; (float)(vars + ssim_c2)
4749 %endif
4750     mulps     m4, m3
4751     mulps     m0, m2
4752     divps     m4, m0  ; ssim
4753
4754     cmp       r2d, 4
4755     je .skip ; faster only if this is the common case; remove branch if we use ssim on a macroblock level
4756     neg       r2
4757 %ifdef PIC
4758     lea       r3, [mask_ff + 16]
4759     movdqu    m1, [r3 + r2*4]
4760 %else
4761     movdqu    m1, [mask_ff + r2*4 + 16]
4762 %endif
4763     pand      m4, m1
4764 .skip:
4765     movhlps   m0, m4
4766     addps     m0, m4
4767     pshuflw   m4, m0, q0032
4768     addss     m0, m4
4769 %if ARCH_X86_64 == 0
4770     movd     r0m, m0
4771     fld     dword r0m
4772 %endif
4773     RET
4774 %endmacro ; SSIM
4775
4776 INIT_XMM sse2
4777 SSIM
4778 INIT_XMM avx
4779 SSIM
4780
4781 ;-----------------------------------------------------------------------------
4782 ; int pixel_asd8( pixel *pix1, intptr_t stride1, pixel *pix2, intptr_t stride2, int height );
4783 ;-----------------------------------------------------------------------------
4784 %macro ASD8 0
4785 cglobal pixel_asd8, 5,5
4786     pxor     m0, m0
4787     pxor     m1, m1
4788 .loop:
4789 %if HIGH_BIT_DEPTH
4790     paddw    m0, [r0]
4791     paddw    m1, [r2]
4792     paddw    m0, [r0+2*r1]
4793     paddw    m1, [r2+2*r3]
4794     lea      r0, [r0+4*r1]
4795     paddw    m0, [r0]
4796     paddw    m1, [r2+4*r3]
4797     lea      r2, [r2+4*r3]
4798     paddw    m0, [r0+2*r1]
4799     paddw    m1, [r2+2*r3]
4800     lea      r0, [r0+4*r1]
4801     lea      r2, [r2+4*r3]
4802 %else
4803     movq     m2, [r0]
4804     movq     m3, [r2]
4805     movhps   m2, [r0+r1]
4806     movhps   m3, [r2+r3]
4807     lea      r0, [r0+2*r1]
4808     psadbw   m2, m1
4809     psadbw   m3, m1
4810     movq     m4, [r0]
4811     movq     m5, [r2+2*r3]
4812     lea      r2, [r2+2*r3]
4813     movhps   m4, [r0+r1]
4814     movhps   m5, [r2+r3]
4815     lea      r0, [r0+2*r1]
4816     paddw    m0, m2
4817     psubw    m0, m3
4818     psadbw   m4, m1
4819     psadbw   m5, m1
4820     lea      r2, [r2+2*r3]
4821     paddw    m0, m4
4822     psubw    m0, m5
4823 %endif
4824     sub     r4d, 4
4825     jg .loop
4826 %if HIGH_BIT_DEPTH
4827     psubw    m0, m1
4828     HADDW    m0, m1
4829     ABSD     m1, m0
4830 %else
4831     movhlps  m1, m0
4832     paddw    m0, m1
4833     ABSW     m1, m0
4834 %endif
4835     movd    eax, m1
4836     RET
4837 %endmacro
4838
4839 INIT_XMM sse2
4840 ASD8
4841 INIT_XMM ssse3
4842 ASD8
4843 %if HIGH_BIT_DEPTH
4844 INIT_XMM xop
4845 ASD8
4846 %endif
4847
4848 ;=============================================================================
4849 ; Successive Elimination ADS
4850 ;=============================================================================
4851
4852 %macro ADS_START 0
4853 %if UNIX64
4854     movsxd  r5, r5d
4855 %else
4856     mov    r5d, r5m
4857 %endif
4858     mov    r0d, r5d
4859     lea     r6, [r4+r5+(mmsize-1)]
4860     and     r6, ~(mmsize-1)
4861     shl     r2d,  1
4862 %endmacro
4863
4864 %macro ADS_END 1 ; unroll_size
4865     add     r1, 8*%1
4866     add     r3, 8*%1
4867     add     r6, 4*%1
4868     sub    r0d, 4*%1
4869     jg .loop
4870     WIN64_RESTORE_XMM rsp
4871 %if mmsize==32
4872     vzeroupper
4873 %endif
4874     lea     r6, [r4+r5+(mmsize-1)]
4875     and     r6, ~(mmsize-1)
4876 %if cpuflag(ssse3)
4877     jmp ads_mvs_ssse3
4878 %else
4879     jmp ads_mvs_mmx
4880 %endif
4881 %endmacro
4882
4883 ;-----------------------------------------------------------------------------
4884 ; int pixel_ads4( int enc_dc[4], uint16_t *sums, int delta,
4885 ;                 uint16_t *cost_mvx, int16_t *mvs, int width, int thresh )
4886 ;-----------------------------------------------------------------------------
4887 INIT_MMX mmx2
4888 cglobal pixel_ads4, 5,7
4889     mova    m6, [r0]
4890     mova    m4, [r0+8]
4891     pshufw  m7, m6, 0
4892     pshufw  m6, m6, q2222
4893     pshufw  m5, m4, 0
4894     pshufw  m4, m4, q2222
4895     ADS_START
4896 .loop:
4897     movu      m0, [r1]
4898     movu      m1, [r1+16]
4899     psubw     m0, m7
4900     psubw     m1, m6
4901     ABSW      m0, m0, m2
4902     ABSW      m1, m1, m3
4903     movu      m2, [r1+r2]
4904     movu      m3, [r1+r2+16]
4905     psubw     m2, m5
4906     psubw     m3, m4
4907     paddw     m0, m1
4908     ABSW      m2, m2, m1
4909     ABSW      m3, m3, m1
4910     paddw     m0, m2
4911     paddw     m0, m3
4912     pshufw    m1, r6m, 0
4913     paddusw   m0, [r3]
4914     psubusw   m1, m0
4915     packsswb  m1, m1
4916     movd    [r6], m1
4917     ADS_END 1
4918
4919 cglobal pixel_ads2, 5,7
4920     mova      m6, [r0]
4921     pshufw    m5, r6m, 0
4922     pshufw    m7, m6, 0
4923     pshufw    m6, m6, q2222
4924     ADS_START
4925 .loop:
4926     movu      m0, [r1]
4927     movu      m1, [r1+r2]
4928     psubw     m0, m7
4929     psubw     m1, m6
4930     ABSW      m0, m0, m2
4931     ABSW      m1, m1, m3
4932     paddw     m0, m1
4933     paddusw   m0, [r3]
4934     mova      m4, m5
4935     psubusw   m4, m0
4936     packsswb  m4, m4
4937     movd    [r6], m4
4938     ADS_END 1
4939
4940 cglobal pixel_ads1, 5,7
4941     pshufw    m7, [r0], 0
4942     pshufw    m6, r6m, 0
4943     ADS_START
4944 .loop:
4945     movu      m0, [r1]
4946     movu      m1, [r1+8]
4947     psubw     m0, m7
4948     psubw     m1, m7
4949     ABSW      m0, m0, m2
4950     ABSW      m1, m1, m3
4951     paddusw   m0, [r3]
4952     paddusw   m1, [r3+8]
4953     mova      m4, m6
4954     mova      m5, m6
4955     psubusw   m4, m0
4956     psubusw   m5, m1
4957     packsswb  m4, m5
4958     mova    [r6], m4
4959     ADS_END 2
4960
4961 %macro ADS_XMM 0
4962 %if mmsize==32
4963 cglobal pixel_ads4, 5,7,8
4964     vpbroadcastw m7, [r0+ 0]
4965     vpbroadcastw m6, [r0+ 4]
4966     vpbroadcastw m5, [r0+ 8]
4967     vpbroadcastw m4, [r0+12]
4968 %else
4969 cglobal pixel_ads4, 5,7,12
4970     mova      m4, [r0]
4971     pshuflw   m7, m4, q0000
4972     pshuflw   m6, m4, q2222
4973     pshufhw   m5, m4, q0000
4974     pshufhw   m4, m4, q2222
4975     punpcklqdq m7, m7
4976     punpcklqdq m6, m6
4977     punpckhqdq m5, m5
4978     punpckhqdq m4, m4
4979 %endif
4980 %if ARCH_X86_64 && mmsize == 16
4981     movd      m8, r6m
4982     SPLATW    m8, m8
4983     ADS_START
4984     movu     m10, [r1]
4985     movu     m11, [r1+r2]
4986 .loop:
4987     psubw     m0, m10, m7
4988     movu     m10, [r1+16]
4989     psubw     m1, m10, m6
4990     ABSW      m0, m0, m2
4991     ABSW      m1, m1, m3
4992     psubw     m2, m11, m5
4993     movu     m11, [r1+r2+16]
4994     paddw     m0, m1
4995     psubw     m3, m11, m4
4996     movu      m9, [r3]
4997     ABSW      m2, m2, m1
4998     ABSW      m3, m3, m1
4999     paddw     m0, m2
5000     paddw     m0, m3
5001     paddusw   m0, m9
5002     psubusw   m1, m8, m0
5003 %else
5004     ADS_START
5005 .loop:
5006     movu      m0, [r1]
5007     movu      m1, [r1+16]
5008     psubw     m0, m7
5009     psubw     m1, m6
5010     ABSW      m0, m0, m2
5011     ABSW      m1, m1, m3
5012     movu      m2, [r1+r2]
5013     movu      m3, [r1+r2+16]
5014     psubw     m2, m5
5015     psubw     m3, m4
5016     paddw     m0, m1
5017     ABSW      m2, m2, m1
5018     ABSW      m3, m3, m1
5019     paddw     m0, m2
5020     paddw     m0, m3
5021     movu      m2, [r3]
5022 %if mmsize==32
5023     vpbroadcastw m1, r6m
5024 %else
5025     movd      m1, r6m
5026     pshuflw   m1, m1, 0
5027     punpcklqdq m1, m1
5028 %endif
5029     paddusw   m0, m2
5030     psubusw   m1, m0
5031 %endif ; ARCH
5032     packsswb  m1, m1
5033 %if mmsize==32
5034     vpermq    m1, m1, q3120
5035     mova    [r6], xm1
5036 %else
5037     movh    [r6], m1
5038 %endif
5039     ADS_END mmsize/8
5040
5041 cglobal pixel_ads2, 5,7,8
5042 %if mmsize==32
5043     vpbroadcastw m7, [r0+0]
5044     vpbroadcastw m6, [r0+4]
5045     vpbroadcastw m5, r6m
5046 %else
5047     movq      m6, [r0]
5048     movd      m5, r6m
5049     pshuflw   m7, m6, 0
5050     pshuflw   m6, m6, q2222
5051     pshuflw   m5, m5, 0
5052     punpcklqdq m7, m7
5053     punpcklqdq m6, m6
5054     punpcklqdq m5, m5
5055 %endif
5056     ADS_START
5057 .loop:
5058     movu      m0, [r1]
5059     movu      m1, [r1+r2]
5060     psubw     m0, m7
5061     psubw     m1, m6
5062     movu      m4, [r3]
5063     ABSW      m0, m0, m2
5064     ABSW      m1, m1, m3
5065     paddw     m0, m1
5066     paddusw   m0, m4
5067     psubusw   m1, m5, m0
5068     packsswb  m1, m1
5069 %if mmsize==32
5070     vpermq    m1, m1, q3120
5071     mova    [r6], xm1
5072 %else
5073     movh    [r6], m1
5074 %endif
5075     ADS_END mmsize/8
5076
5077 cglobal pixel_ads1, 5,7,8
5078 %if mmsize==32
5079     vpbroadcastw m7, [r0]
5080     vpbroadcastw m6, r6m
5081 %else
5082     movd      m7, [r0]
5083     movd      m6, r6m
5084     pshuflw   m7, m7, 0
5085     pshuflw   m6, m6, 0
5086     punpcklqdq m7, m7
5087     punpcklqdq m6, m6
5088 %endif
5089     ADS_START
5090 .loop:
5091     movu      m0, [r1]
5092     movu      m1, [r1+mmsize]
5093     psubw     m0, m7
5094     psubw     m1, m7
5095     movu      m2, [r3]
5096     movu      m3, [r3+mmsize]
5097     ABSW      m0, m0, m4
5098     ABSW      m1, m1, m5
5099     paddusw   m0, m2
5100     paddusw   m1, m3
5101     psubusw   m4, m6, m0
5102     psubusw   m5, m6, m1
5103     packsswb  m4, m5
5104 %if mmsize==32
5105     vpermq    m4, m4, q3120
5106 %endif
5107     mova    [r6], m4
5108     ADS_END mmsize/4
5109 %endmacro
5110
5111 INIT_XMM sse2
5112 ADS_XMM
5113 INIT_XMM ssse3
5114 ADS_XMM
5115 INIT_XMM avx
5116 ADS_XMM
5117 INIT_YMM avx2
5118 ADS_XMM
5119
5120 ; int pixel_ads_mvs( int16_t *mvs, uint8_t *masks, int width )
5121 ; {
5122 ;     int nmv=0, i, j;
5123 ;     *(uint32_t*)(masks+width) = 0;
5124 ;     for( i=0; i<width; i+=8 )
5125 ;     {
5126 ;         uint64_t mask = *(uint64_t*)(masks+i);
5127 ;         if( !mask ) continue;
5128 ;         for( j=0; j<8; j++ )
5129 ;             if( mask & (255<<j*8) )
5130 ;                 mvs[nmv++] = i+j;
5131 ;     }
5132 ;     return nmv;
5133 ; }
5134
5135 %macro TEST 1
5136     mov     [r4+r0*2], r1w
5137     test    r2d, 0xff<<(%1*8)
5138     setne   r3b
5139     add     r0d, r3d
5140     inc     r1d
5141 %endmacro
5142
5143 INIT_MMX mmx
5144 cglobal pixel_ads_mvs, 0,7,0
5145 ads_mvs_mmx:
5146     ; mvs = r4
5147     ; masks = r6
5148     ; width = r5
5149     ; clear last block in case width isn't divisible by 8. (assume divisible by 4, so clearing 4 bytes is enough.)
5150     xor     r0d, r0d
5151     xor     r1d, r1d
5152     mov     [r6+r5], r0d
5153     jmp .loopi
5154 ALIGN 16
5155 .loopi0:
5156     add     r1d, 8
5157     cmp     r1d, r5d
5158     jge .end
5159 .loopi:
5160     mov     r2,  [r6+r1]
5161 %if ARCH_X86_64
5162     test    r2,  r2
5163 %else
5164     mov     r3,  r2
5165     add    r3d, [r6+r1+4]
5166 %endif
5167     jz .loopi0
5168     xor     r3d, r3d
5169     TEST 0
5170     TEST 1
5171     TEST 2
5172     TEST 3
5173 %if ARCH_X86_64
5174     shr     r2,  32
5175 %else
5176     mov     r2d, [r6+r1]
5177 %endif
5178     TEST 0
5179     TEST 1
5180     TEST 2
5181     TEST 3
5182     cmp     r1d, r5d
5183     jl .loopi
5184 .end:
5185     movifnidn eax, r0d
5186     RET
5187
5188 INIT_XMM ssse3
5189 cglobal pixel_ads_mvs, 0,7,0
5190 ads_mvs_ssse3:
5191     mova      m3, [pw_8]
5192     mova      m4, [pw_76543210]
5193     pxor      m5, m5
5194     add       r5, r6
5195     xor      r0d, r0d ; nmv
5196     mov     [r5], r0d
5197 %ifdef PIC
5198     lea       r1, [$$]
5199     %define GLOBAL +r1-$$
5200 %else
5201     %define GLOBAL
5202 %endif
5203 .loop:
5204     movh      m0, [r6]
5205     pcmpeqb   m0, m5
5206     pmovmskb r2d, m0
5207     xor      r2d, 0xffff                         ; skipping if r2d is zero is slower (branch mispredictions)
5208     movzx    r3d, byte [r2+popcnt_table GLOBAL]  ; popcnt
5209     add      r2d, r2d
5210     ; shuffle counters based on mv mask
5211     pshufb    m2, m4, [r2*8+ads_mvs_shuffle GLOBAL]
5212     movu [r4+r0*2], m2
5213     add      r0d, r3d
5214     paddw     m4, m3                             ; {i*8+0, i*8+1, i*8+2, i*8+3, i*8+4, i*8+5, i*8+6, i*8+7}
5215     add       r6, 8
5216     cmp       r6, r5
5217     jl .loop
5218     movifnidn eax, r0d
5219     RET