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