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