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