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