]> git.sesse.net Git - x264/blob - common/x86/pixel-a.asm
74fc7e26a06a9cc576d36bd233e1b9e30da0f7af
[x264] / common / x86 / pixel-a.asm
1 ;*****************************************************************************
2 ;* pixel.asm: x86 pixel metrics
3 ;*****************************************************************************
4 ;* Copyright (C) 2003-2012 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 %ifdef HIGH_BIT_DEPTH
146 ;-----------------------------------------------------------------------------
147 ; int pixel_ssd_MxN( uint16_t *, int, uint16_t *, int )
148 ;-----------------------------------------------------------------------------
149 %macro SSD_ONE 2
150 cglobal pixel_ssd_%1x%2, 4,5,6
151     mov     r4, %1*%2/mmsize
152     pxor    m0, m0
153 .loop
154     mova    m1, [r0]
155 %if %1 <= mmsize/2
156     mova    m3, [r0+r1*2]
157     %define offset r3*2
158     %define num_rows 2
159 %else
160     mova    m3, [r0+mmsize]
161     %define offset mmsize
162     %define num_rows 1
163 %endif
164     lea     r0, [r0+r1*2*num_rows]
165     psubw   m1, [r2]
166     psubw   m3, [r2+offset]
167     lea     r2, [r2+r3*2*num_rows]
168     pmaddwd m1, m1
169     pmaddwd m3, m3
170     paddd   m0, m1
171     paddd   m0, m3
172     dec     r4
173     jg .loop
174     HADDD   m0, m5
175     movd   eax, m0
176     RET
177 %endmacro
178
179 %macro SSD_16_MMX 2
180 cglobal pixel_ssd_%1x%2, 4,5
181     mov     r4, %1*%2/mmsize/2
182     pxor    m0, m0
183 .loop
184     mova    m1, [r0]
185     mova    m2, [r2]
186     mova    m3, [r0+mmsize]
187     mova    m4, [r2+mmsize]
188     mova    m5, [r0+mmsize*2]
189     mova    m6, [r2+mmsize*2]
190     mova    m7, [r0+mmsize*3]
191     psubw   m1, m2
192     psubw   m3, m4
193     mova    m2, [r2+mmsize*3]
194     psubw   m5, m6
195     pmaddwd m1, m1
196     psubw   m7, m2
197     pmaddwd m3, m3
198     pmaddwd m5, m5
199     lea     r0, [r0+r1*2]
200     lea     r2, [r2+r3*2]
201     pmaddwd m7, m7
202     paddd   m1, m3
203     paddd   m5, m7
204     paddd   m0, m1
205     paddd   m0, m5
206     dec     r4
207     jg .loop
208     HADDD   m0, m7
209     movd   eax, m0
210     RET
211 %endmacro
212
213 INIT_MMX mmx2
214 SSD_ONE     4,  4
215 SSD_ONE     4,  8
216 SSD_ONE     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 %ifndef HIGH_BIT_DEPTH
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 *, int, uint8_t *, int )
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 %ifdef 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, int stride1, uint16_t *pixuv2, int 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 %ifdef 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 %ifndef HIGH_BIT_DEPTH
562 ;-----------------------------------------------------------------------------
563 ; void pixel_ssd_nv12_core( uint8_t *pixuv1, int stride1, uint8_t *pixuv2, int 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 %ifndef HIGH_BIT_DEPTH
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 %ifdef 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 %ifdef 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 %ifdef 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 %ifndef HIGH_BIT_DEPTH
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 *, int )
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 %ifdef 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 %ifndef HIGH_BIT_DEPTH
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 *, int, pixel *, int, 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 %ifdef 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 %ifndef ARCH_X86_64
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 %ifdef 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 %ifndef HIGH_BIT_DEPTH
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 %ifdef 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 *, int, uint8_t *, int )
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 %ifdef 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 %ifndef HIGH_BIT_DEPTH
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 %ifdef ARCH_X86_64
1270 %ifdef 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 %ifdef ARCH_X86_64
1280     lea     r0, [r6+8]
1281     lea     r2, [r7+8]
1282 %ifdef 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 *, int, uint8_t *, int )
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 %ifdef 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 %ifdef 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 %ifdef 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 %ifdef 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 %ifdef ARCH_X86_64
1478 ;-----------------------------------------------------------------------------
1479 ; int pixel_sa8d_8x8( uint8_t *, int, uint8_t *, int )
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 %ifdef 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 %ifdef 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 %ifndef HIGH_BIT_DEPTH
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 %ifdef 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 %ifdef 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 %ifdef 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 %ifdef 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 %ifdef 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 %ifdef 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 %ifndef HIGH_BIT_DEPTH
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 %ifdef 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 %ifndef ARCH_X86_64
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 %ifdef 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 %ifdef HIGH_BIT_DEPTH
2010     mova        m7, [pw_1]
2011     pmaddwd     m4, m7
2012     pmaddwd     m0, m7
2013     paddd       m4, [sums+32]
2014     paddd       m0, [sums+24]
2015     mova [sums+32], m4
2016     mova [sums+24], m0
2017     pxor        m7, m7
2018     punpckhwd   m3, m5, m7
2019     punpcklwd   m5, m7
2020     paddd       m3, [sums+48]
2021     paddd       m5, [sums+40]
2022     mova [sums+48], m3
2023     mova [sums+40], m5
2024     mova [sums+ 0], m7
2025     mova [sums+ 8], m7
2026     mova [sums+16], m7
2027 %endif
2028     add         r0, 4*FENC_STRIDEB-16*SIZEOF_PIXEL
2029     inc         r3
2030     jl  .loop_y
2031
2032 ; horizontal sum
2033     movifnidn   r2, r2mp
2034 %ifdef HIGH_BIT_DEPTH
2035     mova        m1, m5
2036     paddd       m5, m3
2037     HADDD       m5, m7 ; DC satd
2038     HADDD       m4, m7 ; H satd
2039     HADDD       m0, m7 ; the part of V satd that doesn't overlap with DC
2040     psrld       m0, 1
2041     psrlq       m1, 32 ; DC[1]
2042     paddd       m0, m3 ; DC[2]
2043     psrlq       m3, 32 ; DC[3]
2044     paddd       m0, m1
2045     paddd       m0, m3
2046 %else
2047     mova        m7, m5
2048     SUM_MM_X3   m0, m4, m5, m3, m1, m2, m6, paddd
2049     psrld       m0, 1
2050     pslld       m7, 16
2051     psrld       m7, 16
2052     paddd       m0, m5
2053     psubd       m0, m7
2054 %endif
2055     movd    [r2+8], m5 ; i16x16_dc satd
2056     movd    [r2+4], m4 ; i16x16_h satd
2057     movd    [r2+0], m0 ; i16x16_v satd
2058     ADD        rsp, stack_pad
2059     RET
2060
2061 %ifdef ARCH_X86_64
2062     %define  t0 r6
2063 %else
2064     %define  t0 r2
2065 %endif
2066
2067 ;-----------------------------------------------------------------------------
2068 ; void intra_satd_x3_8x8c( uint8_t *fenc, uint8_t *fdec, int *res )
2069 ;-----------------------------------------------------------------------------
2070 cglobal intra_satd_x3_8x8c, 0,6
2071     ; not really needed on x86_64, just shuts up valgrind about storing data below the stack across a function call
2072     SUB          rsp, 72
2073 %define  sums    rsp+48 ; size 24
2074 %define  dc_1d   rsp+32 ; size 16
2075 %define  top_1d  rsp+16 ; size 16
2076 %define  left_1d rsp    ; size 16
2077     movifnidn   r1,  r1mp
2078     pxor        m7, m7
2079     mova [sums+ 0], m7
2080     mova [sums+ 8], m7
2081     mova [sums+16], m7
2082
2083     ; 1D hadamards
2084     mov         r3d, 4
2085 .loop_edge:
2086     SCALAR_HADAMARD left, r3, m0, m1
2087     SCALAR_HADAMARD top,  r3, m0, m1, m2
2088     sub         r3d, 4
2089     jge .loop_edge
2090
2091     ; dc
2092     movzx       t0d, word [left_1d+0]
2093     movzx       r3d, word [top_1d+0]
2094     movzx       r4d, word [left_1d+8]
2095     movzx       r5d, word [top_1d+8]
2096     lea         t0d, [t0 + r3 + 16]
2097     lea         r3d, [r4 + r5 + 16]
2098     shr         t0d, 1
2099     shr         r3d, 1
2100     add         r4d, 8
2101     add         r5d, 8
2102     and         t0d, -16 ; tl
2103     and         r3d, -16 ; br
2104     and         r4d, -16 ; bl
2105     and         r5d, -16 ; tr
2106     mov         [dc_1d+ 0], t0d ; tl
2107     mov         [dc_1d+ 4], r5d ; tr
2108     mov         [dc_1d+ 8], r4d ; bl
2109     mov         [dc_1d+12], r3d ; br
2110     lea         r5, [dc_1d]
2111
2112     ; 2D hadamards
2113     movifnidn   r0,  r0mp
2114     movifnidn   r2,  r2mp
2115     mov         r3,  -2
2116 .loop_y:
2117     mov         r4,  -2
2118 .loop_x:
2119     call hadamard_load
2120
2121     SUM3x4
2122     SUM4x3 [r5+4*(r4+2)], [left_1d+8*(r3+2)], [top_1d+8*(r4+2)]
2123     pavgw       m4, m7
2124     pavgw       m5, m7
2125     paddw       m0, [sums+16] ; i4x4_v satd
2126     paddw       m4, [sums+8]  ; i4x4_h satd
2127     paddw       m5, [sums+0]  ; i4x4_dc satd
2128     movq        [sums+16], m0
2129     movq        [sums+8], m4
2130     movq        [sums+0], m5
2131
2132     add         r0, 4*SIZEOF_PIXEL
2133     inc         r4
2134     jl  .loop_x
2135     add         r0, 4*FENC_STRIDEB-8*SIZEOF_PIXEL
2136     add         r5, 8
2137     inc         r3
2138     jl  .loop_y
2139
2140 ; horizontal sum
2141     movq        m0, [sums+0]
2142     movq        m1, [sums+8]
2143     movq        m2, [sums+16]
2144     movq        m7, m0
2145 %ifdef HIGH_BIT_DEPTH
2146     psrlq       m7, 16
2147     HADDW       m7, m3
2148     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
2149     psrld       m2, 1
2150     paddd       m2, m7
2151 %else
2152     psrlq       m7, 15
2153     paddw       m2, m7
2154     SUM_MM_X3   m0, m1, m2, m3, m4, m5, m6, paddd
2155     psrld       m2, 1
2156 %endif
2157     movd        [r2+0], m0 ; i8x8c_dc satd
2158     movd        [r2+4], m1 ; i8x8c_h satd
2159     movd        [r2+8], m2 ; i8x8c_v satd
2160     ADD         rsp, 72
2161     RET
2162 %endmacro ; INTRA_X3_MMX
2163
2164
2165
2166 %macro PRED4x4_LOWPASS 5
2167 %ifid %5
2168     pavgb       %5, %2, %3
2169     pxor        %3, %2
2170     pand        %3, [pb_1]
2171     psubusb     %5, %3
2172     pavgb       %1, %4, %5
2173 %else
2174     mova        %5, %2
2175     pavgb       %2, %3
2176     pxor        %3, %5
2177     pand        %3, [pb_1]
2178     psubusb     %2, %3
2179     pavgb       %1, %4, %2
2180 %endif
2181 %endmacro
2182
2183 %macro INTRA_X9_PRED 2
2184 %if cpuflag(sse4)
2185     movu       m1, [r1-1*FDEC_STRIDE-8]
2186     pinsrb     m1, [r1+3*FDEC_STRIDE-1], 0
2187     pinsrb     m1, [r1+2*FDEC_STRIDE-1], 1
2188     pinsrb     m1, [r1+1*FDEC_STRIDE-1], 2
2189     pinsrb     m1, [r1+0*FDEC_STRIDE-1], 3
2190 %else
2191     movd      mm0, [r1+3*FDEC_STRIDE-4]
2192     punpcklbw mm0, [r1+2*FDEC_STRIDE-4]
2193     movd      mm1, [r1+1*FDEC_STRIDE-4]
2194     punpcklbw mm1, [r1+0*FDEC_STRIDE-4]
2195     punpckhwd mm0, mm1
2196     psrlq     mm0, 32
2197     movq2dq    m0, mm0
2198     movu       m1, [r1-1*FDEC_STRIDE-8]
2199     movss      m1, m0                  ; l3 l2 l1 l0 __ __ __ lt t0 t1 t2 t3 t4 t5 t6 t7
2200 %endif ; cpuflag
2201     pshufb     m1, [intrax9_edge]      ; l3 l3 l2 l1 l0 lt t0 t1 t2 t3 t4 t5 t6 t7 t7 __
2202     psrldq     m0, m1, 1               ; l3 l2 l1 l0 lt t0 t1 t2 t3 t4 t5 t6 t7 t7 __ __
2203     psrldq     m2, m1, 2               ; l2 l1 l0 lt t0 t1 t2 t3 t4 t5 t6 t7 t7 __ __ __
2204     pavgb      m5, m0, m1              ; Gl3 Gl2 Gl1 Gl0 Glt Gt0 Gt1 Gt2 Gt3 Gt4 Gt5  __  __ __ __ __
2205     mova       %2, m1
2206     PRED4x4_LOWPASS m0, m1, m2, m0, m4 ; Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 __ __ __
2207     ; ddl               ddr
2208     ; Ft1 Ft2 Ft3 Ft4   Flt Ft0 Ft1 Ft2
2209     ; Ft2 Ft3 Ft4 Ft5   Fl0 Flt Ft0 Ft1
2210     ; Ft3 Ft4 Ft5 Ft6   Fl1 Fl0 Flt Ft0
2211     ; Ft4 Ft5 Ft6 Ft7   Fl2 Fl1 Fl0 Flt
2212     pshufb     m2, m0, [%1_ddlr1] ; a: ddl row0, ddl row1, ddr row0, ddr row1 / b: ddl row0, ddr row0, ddl row1, ddr row1
2213     pshufb     m3, m0, [%1_ddlr2] ; rows 2,3
2214     ; hd                hu
2215     ; Glt Flt Ft0 Ft1   Gl0 Fl1 Gl1 Fl2
2216     ; Gl0 Fl0 Glt Flt   Gl1 Fl2 Gl2 Fl3
2217     ; Gl1 Fl1 Gl0 Fl0   Gl2 Fl3 Gl3 Gl3
2218     ; Gl2 Fl2 Gl1 Fl1   Gl3 Gl3 Gl3 Gl3
2219     pslldq     m0, 5                   ; ___ ___ ___ ___ ___ Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5
2220     palignr    m7, m5, m0, 5           ; Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Gl3 Gl2 Gl1 Gl0 Glt
2221     pshufb     m6, m7, [%1_hdu1]
2222     pshufb     m7, m7, [%1_hdu2]
2223     ; vr                vl
2224     ; Gt0 Gt1 Gt2 Gt3   Gt1 Gt2 Gt3 Gt4
2225     ; Flt Ft0 Ft1 Ft2   Ft1 Ft2 Ft3 Ft4
2226     ; Fl0 Gt0 Gt1 Gt2   Gt2 Gt3 Gt4 Gt5
2227     ; Fl1 Flt Ft0 Ft1   Ft2 Ft3 Ft4 Ft5
2228     psrldq     m5, 5                   ; Gt0 Gt1 Gt2 Gt3 Gt4 Gt5 ...
2229     palignr    m5, m0, 6               ; ___ Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Gt0 Gt1 Gt2 Gt3 Gt4 Gt5
2230     pshufb     m4, m5, [%1_vrl1]
2231     pshufb     m5, m5, [%1_vrl2]
2232 %endmacro ; INTRA_X9_PRED
2233
2234 %macro INTRA_X9_VHDC 5 ; edge, fenc01, fenc23, tmp, tmp
2235     pshufb     m2, m%1, [intrax9b_vh1]
2236     pshufb     m3, m%1, [intrax9b_vh2]
2237     mova      [pred_buf+0x60], m2
2238     mova      [pred_buf+0x70], m3
2239     pshufb    m%1, [intrax9b_edge2] ; t0 t1 t2 t3 t0 t1 t2 t3 l0 l1 l2 l3 l0 l1 l2 l3
2240     pmaddubsw m%1, [hmul_4p]
2241     pshufhw    m0, m%1, q2301
2242     pshuflw    m0, m0,  q2301
2243     psignw    m%1, [pw_pmpmpmpm]
2244     paddw      m0, m%1
2245     psllw      m0, 2 ; hadamard(top), hadamard(left)
2246     movhlps    m3, m0
2247     pshufb     m1, m0, [intrax9b_v1]
2248     pshufb     m2, m0, [intrax9b_v2]
2249     paddw      m0, m3
2250     psignw     m3, [pw_pmmpzzzz] ; FIXME could this be eliminated?
2251     pavgw      m0, [pw_16]
2252     pand       m0, [sw_f0] ; dc
2253     ; This (as well as one of the steps in intra_satd_x9_4x4.satd_8x4) could be
2254     ; changed from a wd transpose to a qdq, with appropriate rearrangement of inputs.
2255     ; Which would be faster on conroe, but slower on penryn and sandybridge, and too invasive to ifdef.
2256     HADAMARD 0, sumsub, %2, %3, %4, %5
2257     HADAMARD 1, sumsub, %2, %3, %4, %5
2258     movd      r3d, m0
2259     shr       r3d, 4
2260     imul      r3d, 0x01010101
2261     mov       [pred_buf+0x80], r3d
2262     mov       [pred_buf+0x88], r3d
2263     mov       [pred_buf+0x90], r3d
2264     mov       [pred_buf+0x98], r3d
2265     psubw      m3, m%2
2266     psubw      m0, m%2
2267     psubw      m1, m%2
2268     psubw      m2, m%3
2269     pabsw     m%3, m%3
2270     pabsw      m3, m3
2271     pabsw      m0, m0
2272     pabsw      m1, m1
2273     pabsw      m2, m2
2274     pavgw      m3, m%3
2275     pavgw      m0, m%3
2276     pavgw      m1, m2
2277 %if cpuflag(sse4)
2278     phaddw     m3, m0
2279 %else
2280     SBUTTERFLY qdq, 3, 0, 2
2281     paddw      m3, m0
2282 %endif
2283     movhlps    m2, m1
2284     paddw      m1, m2
2285 %if cpuflag(xop)
2286     vphaddwq   m3, m3
2287     vphaddwq   m1, m1
2288     packssdw   m1, m3
2289 %else
2290     phaddw     m1, m3
2291     pmaddwd    m1, [pw_1] ; v, _, h, dc
2292 %endif
2293 %endmacro ; INTRA_X9_VHDC
2294
2295 %macro INTRA_X9_END 2
2296 %if cpuflag(sse4)
2297     phminposuw m0, m0 ; h,dc,ddl,ddr,vr,hd,vl,hu
2298     movd      eax, m0
2299     add       eax, 1<<16
2300     cmp        ax, r3w
2301     cmovge    eax, r3d
2302 %else
2303 %if %1
2304     ; 4x4 sad is up to 12 bits; +bitcosts -> 13 bits; pack with 3 bit index
2305     psllw      m0, 3
2306     paddw      m0, [pw_s01234567] ; h,dc,ddl,ddr,vr,hd,vl,hu
2307 %else
2308     ; 4x4 satd is up to 13 bits; +bitcosts and saturate -> 13 bits; pack with 3 bit index
2309     psllw      m0, 2
2310     paddusw    m0, m0
2311     paddw      m0, [pw_s01234657] ; h,dc,ddl,ddr,vr,vl,hd,hu
2312 %endif
2313     movhlps    m1, m0
2314     pminsw     m0, m1
2315     pshuflw    m1, m0, q0032
2316     pminsw     m0, m1
2317     pshuflw    m1, m0, q0001
2318     pminsw     m0, m1
2319     movd      eax, m0
2320     movsx     r2d, ax
2321     and       eax, 7
2322     sar       r2d, 3
2323     shl       eax, 16
2324     ; 1<<16: increment index to match intra4x4_pred_e. couldn't do this before because it had to fit in 3 bits
2325     ; 1<<12: undo sign manipulation
2326     lea       eax, [rax+r2+(1<<16)+(1<<12)]
2327     cmp        ax, r3w
2328     cmovge    eax, r3d
2329 %endif ; cpuflag
2330
2331     ; output the predicted samples
2332     mov       r3d, eax
2333     shr       r3d, 16
2334 %ifdef PIC
2335     lea        r2, [%2_lut]
2336     movzx     r2d, byte [r2+r3]
2337 %else
2338     movzx     r2d, byte [%2_lut+r3]
2339 %endif
2340 %if %1 ; sad
2341     movq      mm0, [pred_buf+r2]
2342     movq      mm1, [pred_buf+r2+16]
2343     movd     [r1+0*FDEC_STRIDE], mm0
2344     movd     [r1+2*FDEC_STRIDE], mm1
2345     psrlq     mm0, 32
2346     psrlq     mm1, 32
2347     movd     [r1+1*FDEC_STRIDE], mm0
2348     movd     [r1+3*FDEC_STRIDE], mm1
2349 %else ; satd
2350 %assign i 0
2351 %rep 4
2352     mov       r3d, [pred_buf+r2+8*i]
2353     mov      [r1+i*FDEC_STRIDE], r3d
2354 %assign i i+1
2355 %endrep
2356 %endif
2357 %endmacro ; INTRA_X9_END
2358
2359 %macro INTRA_X9 0
2360 ;-----------------------------------------------------------------------------
2361 ; int intra_sad_x9_4x4( uint8_t *fenc, uint8_t *fdec, uint16_t *bitcosts )
2362 ;-----------------------------------------------------------------------------
2363 %if notcpuflag(xop)
2364 cglobal intra_sad_x9_4x4, 3,4,9
2365     %assign pad 0xc0-gprsize-(stack_offset&15)
2366     %define pred_buf rsp
2367     sub       rsp, pad
2368 %ifdef ARCH_X86_64
2369     INTRA_X9_PRED intrax9a, m8
2370 %else
2371     INTRA_X9_PRED intrax9a, [rsp+0xa0]
2372 %endif
2373     mova [rsp+0x00], m2
2374     mova [rsp+0x10], m3
2375     mova [rsp+0x20], m4
2376     mova [rsp+0x30], m5
2377     mova [rsp+0x40], m6
2378     mova [rsp+0x50], m7
2379 %if cpuflag(sse4)
2380     movd       m0, [r0+0*FENC_STRIDE]
2381     pinsrd     m0, [r0+1*FENC_STRIDE], 1
2382     movd       m1, [r0+2*FENC_STRIDE]
2383     pinsrd     m1, [r0+3*FENC_STRIDE], 1
2384 %else
2385     movd      mm0, [r0+0*FENC_STRIDE]
2386     punpckldq mm0, [r0+1*FENC_STRIDE]
2387     movd      mm1, [r0+2*FENC_STRIDE]
2388     punpckldq mm1, [r0+3*FENC_STRIDE]
2389     movq2dq    m0, mm0
2390     movq2dq    m1, mm1
2391 %endif
2392     punpcklqdq m0, m0
2393     punpcklqdq m1, m1
2394     psadbw     m2, m0
2395     psadbw     m3, m1
2396     psadbw     m4, m0
2397     psadbw     m5, m1
2398     psadbw     m6, m0
2399     psadbw     m7, m1
2400     paddd      m2, m3
2401     paddd      m4, m5
2402     paddd      m6, m7
2403 %ifdef ARCH_X86_64
2404     SWAP        7, 8
2405     pxor       m8, m8
2406     %define %%zero m8
2407 %else
2408     mova       m7, [rsp+0xa0]
2409     %define %%zero [pb_0]
2410 %endif
2411     pshufb     m3, m7, [intrax9a_vh1]
2412     pshufb     m5, m7, [intrax9a_vh2]
2413     pshufb     m7, [intrax9a_dc]
2414     psadbw     m7, %%zero
2415     psrlw      m7, 2
2416     mova [rsp+0x60], m3
2417     mova [rsp+0x70], m5
2418     psadbw     m3, m0
2419     pavgw      m7, %%zero
2420     pshufb     m7, %%zero
2421     psadbw     m5, m1
2422     movq [rsp+0x80], m7
2423     movq [rsp+0x90], m7
2424     psadbw     m0, m7
2425     paddd      m3, m5
2426     psadbw     m1, m7
2427     paddd      m0, m1
2428     movzx     r3d, word [r2]
2429     movd      r0d, m3 ; v
2430     add       r3d, r0d
2431     punpckhqdq m3, m0 ; h, dc
2432     shufps     m3, m2, q2020
2433     psllq      m6, 32
2434     por        m4, m6
2435     movu       m0, [r2+2]
2436     packssdw   m3, m4
2437     paddw      m0, m3
2438     INTRA_X9_END 1, intrax9a
2439     add       rsp, pad
2440     RET
2441 %endif ; cpuflag
2442
2443 %ifdef ARCH_X86_64
2444 ;-----------------------------------------------------------------------------
2445 ; int intra_satd_x9_4x4( uint8_t *fenc, uint8_t *fdec, uint16_t *bitcosts )
2446 ;-----------------------------------------------------------------------------
2447 cglobal intra_satd_x9_4x4, 3,4,16
2448     %assign pad 0xb0-gprsize-(stack_offset&15)
2449     %define pred_buf rsp
2450     sub       rsp, pad
2451     INTRA_X9_PRED intrax9b, m15
2452     mova [rsp+0x00], m2
2453     mova [rsp+0x10], m3
2454     mova [rsp+0x20], m4
2455     mova [rsp+0x30], m5
2456     mova [rsp+0x40], m6
2457     mova [rsp+0x50], m7
2458     movd       m8, [r0+0*FENC_STRIDE]
2459     movd       m9, [r0+1*FENC_STRIDE]
2460     movd      m10, [r0+2*FENC_STRIDE]
2461     movd      m11, [r0+3*FENC_STRIDE]
2462     mova      m12, [hmul_8p]
2463     pshufd     m8, m8, 0
2464     pshufd     m9, m9, 0
2465     pshufd    m10, m10, 0
2466     pshufd    m11, m11, 0
2467     pmaddubsw  m8, m12
2468     pmaddubsw  m9, m12
2469     pmaddubsw m10, m12
2470     pmaddubsw m11, m12
2471     movddup    m0, m2
2472     pshufd     m1, m2, q3232
2473     movddup    m2, m3
2474     movhlps    m3, m3
2475     call .satd_8x4 ; ddr, ddl
2476     movddup    m2, m5
2477     pshufd     m3, m5, q3232
2478     mova       m5, m0
2479     movddup    m0, m4
2480     pshufd     m1, m4, q3232
2481     call .satd_8x4 ; vr, vl
2482     movddup    m2, m7
2483     pshufd     m3, m7, q3232
2484     mova       m4, m0
2485     movddup    m0, m6
2486     pshufd     m1, m6, q3232
2487     call .satd_8x4 ; hd, hu
2488 %if cpuflag(sse4)
2489     punpckldq  m4, m0
2490 %else
2491     punpcklqdq m4, m0 ; conroe dislikes punpckldq, and ssse3 INTRA_X9_END can handle arbitrary orders whereas phminposuw can't
2492 %endif
2493     mova       m1, [pw_ppmmppmm]
2494     psignw     m8, m1
2495     psignw    m10, m1
2496     paddw      m8, m9
2497     paddw     m10, m11
2498     INTRA_X9_VHDC 15, 8, 10, 6, 7
2499     ; find minimum
2500     movu       m0, [r2+2]
2501     movd      r3d, m1
2502     palignr    m5, m1, 8
2503 %if notcpuflag(sse4)
2504     pshufhw    m0, m0, q3120 ; compensate for different order in unpack
2505 %endif
2506     packssdw   m5, m4
2507     paddw      m0, m5
2508     movzx     r0d, word [r2]
2509     add       r3d, r0d
2510     INTRA_X9_END 0, intrax9b
2511     add       rsp, pad
2512     RET
2513 RESET_MM_PERMUTATION
2514 ALIGN 16
2515 .satd_8x4:
2516     pmaddubsw  m0, m12
2517     pmaddubsw  m1, m12
2518     pmaddubsw  m2, m12
2519     pmaddubsw  m3, m12
2520     psubw      m0, m8
2521     psubw      m1, m9
2522     psubw      m2, m10
2523     psubw      m3, m11
2524     SATD_8x4_SSE cpuname, 0, 1, 2, 3, 13, 14, 0, swap
2525     pmaddwd    m0, [pw_1]
2526 %if cpuflag(sse4)
2527     pshufd     m1, m0, q0032
2528 %else
2529     movhlps    m1, m0
2530 %endif
2531     paddd    xmm0, m0, m1 ; consistent location of return value. only the avx version of hadamard permutes m0, so 3arg is free
2532     ret
2533
2534 %else ; !ARCH_X86_64
2535 cglobal intra_satd_x9_4x4, 3,4,8
2536     %assign pad 0x120-gprsize-(stack_offset&15)
2537     %define fenc_buf rsp
2538     %define pred_buf rsp+0x40
2539     %define spill    rsp+0xe0
2540     sub       rsp, pad
2541     INTRA_X9_PRED intrax9b, [spill+0x20]
2542     mova [pred_buf+0x00], m2
2543     mova [pred_buf+0x10], m3
2544     mova [pred_buf+0x20], m4
2545     mova [pred_buf+0x30], m5
2546     mova [pred_buf+0x40], m6
2547     mova [pred_buf+0x50], m7
2548     movd       m4, [r0+0*FENC_STRIDE]
2549     movd       m5, [r0+1*FENC_STRIDE]
2550     movd       m6, [r0+2*FENC_STRIDE]
2551     movd       m0, [r0+3*FENC_STRIDE]
2552     mova       m7, [hmul_8p]
2553     pshufd     m4, m4, 0
2554     pshufd     m5, m5, 0
2555     pshufd     m6, m6, 0
2556     pshufd     m0, m0, 0
2557     pmaddubsw  m4, m7
2558     pmaddubsw  m5, m7
2559     pmaddubsw  m6, m7
2560     pmaddubsw  m0, m7
2561     mova [fenc_buf+0x00], m4
2562     mova [fenc_buf+0x10], m5
2563     mova [fenc_buf+0x20], m6
2564     mova [fenc_buf+0x30], m0
2565     movddup    m0, m2
2566     pshufd     m1, m2, q3232
2567     movddup    m2, m3
2568     movhlps    m3, m3
2569     pmaddubsw  m0, m7
2570     pmaddubsw  m1, m7
2571     pmaddubsw  m2, m7
2572     pmaddubsw  m3, m7
2573     psubw      m0, m4
2574     psubw      m1, m5
2575     psubw      m2, m6
2576     call .satd_8x4b ; ddr, ddl
2577     mova       m3, [pred_buf+0x30]
2578     mova       m1, [pred_buf+0x20]
2579     movddup    m2, m3
2580     movhlps    m3, m3
2581     movq [spill+0x08], m0
2582     movddup    m0, m1
2583     movhlps    m1, m1
2584     call .satd_8x4 ; vr, vl
2585     mova       m3, [pred_buf+0x50]
2586     mova       m1, [pred_buf+0x40]
2587     movddup    m2, m3
2588     movhlps    m3, m3
2589     movq [spill+0x10], m0
2590     movddup    m0, m1
2591     movhlps    m1, m1
2592     call .satd_8x4 ; hd, hu
2593     movq [spill+0x18], m0
2594     mova       m1, [spill+0x20]
2595     mova       m4, [fenc_buf+0x00]
2596     mova       m5, [fenc_buf+0x20]
2597     mova       m2, [pw_ppmmppmm]
2598     psignw     m4, m2
2599     psignw     m5, m2
2600     paddw      m4, [fenc_buf+0x10]
2601     paddw      m5, [fenc_buf+0x30]
2602     INTRA_X9_VHDC 1, 4, 5, 6, 7
2603     ; find minimum
2604     movu       m0, [r2+2]
2605     movd      r3d, m1
2606     punpckhqdq m1, [spill+0x00]
2607     packssdw   m1, [spill+0x10]
2608 %if cpuflag(sse4)
2609     pshufhw    m1, m1, q3120
2610 %else
2611     pshufhw    m0, m0, q3120
2612 %endif
2613     paddw      m0, m1
2614     movzx     r0d, word [r2]
2615     add       r3d, r0d
2616     INTRA_X9_END 0, intrax9b
2617     add       rsp, pad
2618     RET
2619 RESET_MM_PERMUTATION
2620 ALIGN 16
2621 .satd_8x4:
2622     pmaddubsw  m0, m7
2623     pmaddubsw  m1, m7
2624     pmaddubsw  m2, m7
2625     pmaddubsw  m3, m7
2626     %xdefine fenc_buf fenc_buf+gprsize
2627     psubw      m0, [fenc_buf+0x00]
2628     psubw      m1, [fenc_buf+0x10]
2629     psubw      m2, [fenc_buf+0x20]
2630 .satd_8x4b:
2631     psubw      m3, [fenc_buf+0x30]
2632     SATD_8x4_SSE cpuname, 0, 1, 2, 3, 4, 5, 0, swap
2633     pmaddwd    m0, [pw_1]
2634 %if cpuflag(sse4)
2635     pshufd     m1, m0, q0032
2636 %else
2637     movhlps    m1, m0
2638 %endif
2639     paddd    xmm0, m0, m1
2640     ret
2641 %endif ; ARCH
2642 %endmacro ; INTRA_X9
2643
2644
2645
2646 %macro INTRA8_X9 0
2647 ;-----------------------------------------------------------------------------
2648 ; int intra_sad_x9_8x8( uint8_t *fenc, uint8_t *fdec, uint8_t edge[36], uint16_t *bitcosts, uint16_t *satds )
2649 ;-----------------------------------------------------------------------------
2650 cglobal intra_sad_x9_8x8, 5,6,9
2651     %define fenc02 m4
2652     %define fenc13 m5
2653     %define fenc46 m6
2654     %define fenc57 m7
2655 %ifdef ARCH_X86_64
2656     %define tmp m8
2657     %assign padbase 0x0
2658 %else
2659     %define tmp [rsp]
2660     %assign padbase 0x10
2661 %endif
2662     %assign pad 0x240+0x10+padbase-gprsize-(stack_offset&15)
2663     %define pred(i,j) [rsp+i*0x40+j*0x10+padbase]
2664
2665     SUB        rsp, pad
2666     movq    fenc02, [r0+FENC_STRIDE* 0]
2667     movq    fenc13, [r0+FENC_STRIDE* 1]
2668     movq    fenc46, [r0+FENC_STRIDE* 4]
2669     movq    fenc57, [r0+FENC_STRIDE* 5]
2670     movhps  fenc02, [r0+FENC_STRIDE* 2]
2671     movhps  fenc13, [r0+FENC_STRIDE* 3]
2672     movhps  fenc46, [r0+FENC_STRIDE* 6]
2673     movhps  fenc57, [r0+FENC_STRIDE* 7]
2674
2675     ; save instruction size: avoid 4-byte memory offsets
2676     lea         r0, [intra8x9_h1+128]
2677     %define off(m) (r0+m-(intra8x9_h1+128))
2678
2679 ; v
2680     movddup     m0, [r2+16]
2681     mova pred(0,0), m0
2682     psadbw      m1, m0, fenc02
2683     mova pred(0,1), m0
2684     psadbw      m2, m0, fenc13
2685     mova pred(0,2), m0
2686     psadbw      m3, m0, fenc46
2687     mova pred(0,3), m0
2688     psadbw      m0, m0, fenc57
2689     paddw       m1, m2
2690     paddw       m0, m3
2691     paddw       m0, m1
2692     movhlps     m1, m0
2693     paddw       m0, m1
2694     movd    [r4+0], m0
2695
2696 ; h
2697     movq        m0, [r2+7]
2698     pshufb      m1, m0, [off(intra8x9_h1)]
2699     pshufb      m2, m0, [off(intra8x9_h2)]
2700     mova pred(1,0), m1
2701     psadbw      m1, fenc02
2702     mova pred(1,1), m2
2703     psadbw      m2, fenc13
2704     paddw       m1, m2
2705     pshufb      m3, m0, [off(intra8x9_h3)]
2706     pshufb      m2, m0, [off(intra8x9_h4)]
2707     mova pred(1,2), m3
2708     psadbw      m3, fenc46
2709     mova pred(1,3), m2
2710     psadbw      m2, fenc57
2711     paddw       m1, m3
2712     paddw       m1, m2
2713     movhlps     m2, m1
2714     paddw       m1, m2
2715     movd    [r4+2], m1
2716
2717     lea         r5, [rsp+padbase+0x100]
2718     %define pred(i,j) [r5+i*0x40+j*0x10-0x100]
2719
2720 ; dc
2721     movhps      m0, [r2+16]
2722     pxor        m2, m2
2723     psadbw      m0, m2
2724     movhlps     m1, m0
2725     paddw       m0, m1
2726     psrlw       m0, 3
2727     pavgw       m0, m2
2728     pshufb      m0, m2
2729     mova pred(2,0), m0
2730     psadbw      m1, m0, fenc02
2731     mova pred(2,1), m0
2732     psadbw      m2, m0, fenc13
2733     mova pred(2,2), m0
2734     psadbw      m3, m0, fenc46
2735     mova pred(2,3), m0
2736     psadbw      m0, m0, fenc57
2737     paddw       m1, m2
2738     paddw       m0, m3
2739     paddw       m0, m1
2740     movhlps     m1, m0
2741     paddw       m0, m1
2742     movd    [r4+4], m0
2743
2744 ; ddl
2745 ; Ft1 Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 Ft8
2746 ; Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 Ft8 Ft9
2747 ; Ft3 Ft4 Ft5 Ft6 Ft7 Ft8 Ft9 FtA
2748 ; Ft4 Ft5 Ft6 Ft7 Ft8 Ft9 FtA FtB
2749 ; Ft5 Ft6 Ft7 Ft8 Ft9 FtA FtB FtC
2750 ; Ft6 Ft7 Ft8 Ft9 FtA FtB FtC FtD
2751 ; Ft7 Ft8 Ft9 FtA FtB FtC FtD FtE
2752 ; Ft8 Ft9 FtA FtB FtC FtD FtE FtF
2753     mova        m0, [r2+16]
2754     movu        m2, [r2+17]
2755     pslldq      m1, m0, 1
2756     pavgb       m3, m0, m2              ; Gt1 Gt2 Gt3 Gt4 Gt5 Gt6 Gt7 Gt8 Gt9 GtA GtB ___ ___ ___ ___ ___
2757     PRED4x4_LOWPASS m0, m1, m2, m0, tmp ; ___ Ft1 Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 Ft8 Ft9 FtA FtB FtC FtD FtE FtF
2758     pshufb      m1, m0, [off(intra8x9_ddl1)]
2759     pshufb      m2, m0, [off(intra8x9_ddl2)]
2760     mova pred(3,0), m1
2761     psadbw      m1, fenc02
2762     mova pred(3,1), m2
2763     psadbw      m2, fenc13
2764     paddw       m1, m2
2765     pshufb      m2, m0, [off(intra8x9_ddl3)]
2766     mova pred(3,2), m2
2767     psadbw      m2, fenc46
2768     paddw       m1, m2
2769     pshufb      m2, m0, [off(intra8x9_ddl4)]
2770     mova pred(3,3), m2
2771     psadbw      m2, fenc57
2772     paddw       m1, m2
2773     movhlps     m2, m1
2774     paddw       m1, m2
2775     movd    [r4+6], m1
2776
2777 ; vl
2778 ; Gt1 Gt2 Gt3 Gt4 Gt5 Gt6 Gt7 Gt8
2779 ; Ft1 Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 Ft8
2780 ; Gt2 Gt3 Gt4 Gt5 Gt6 Gt7 Gt8 Gt9
2781 ; Ft2 Ft3 Ft4 Ft5 Ft6 Ft7 Ft8 Ft9
2782 ; Gt3 Gt4 Gt5 Gt6 Gt7 Gt8 Gt9 GtA
2783 ; Ft3 Ft4 Ft5 Ft6 Ft7 Ft8 Ft9 FtA
2784 ; Gt4 Gt5 Gt6 Gt7 Gt8 Gt9 GtA GtB
2785 ; Ft4 Ft5 Ft6 Ft7 Ft8 Ft9 FtA FtB
2786     pshufb      m1, m3, [off(intra8x9_vl1)]
2787     pshufb      m2, m0, [off(intra8x9_vl2)]
2788     pshufb      m3, m3, [off(intra8x9_vl3)]
2789     pshufb      m0, m0, [off(intra8x9_vl4)]
2790     mova pred(7,0), m1
2791     psadbw      m1, fenc02
2792     mova pred(7,1), m2
2793     psadbw      m2, fenc13
2794     mova pred(7,2), m3
2795     psadbw      m3, fenc46
2796     mova pred(7,3), m0
2797     psadbw      m0, fenc57
2798     paddw       m1, m2
2799     paddw       m0, m3
2800     paddw       m0, m1
2801     movhlps     m1, m0
2802     paddw       m0, m1
2803 %if cpuflag(sse4)
2804     pextrw [r4+14], m0, 0
2805 %else
2806     movd       r5d, m0
2807     mov    [r4+14], r5w
2808     lea         r5, [rsp+padbase+0x100]
2809 %endif
2810
2811 ; ddr
2812 ; Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Ft6
2813 ; Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5
2814 ; Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4
2815 ; Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3
2816 ; Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2
2817 ; Fl4 Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1
2818 ; Fl5 Fl4 Fl3 Fl2 Fl1 Fl0 Flt Ft0
2819 ; Fl6 Fl5 Fl4 Fl3 Fl2 Fl1 Fl0 Flt
2820     movu        m2, [r2+8]
2821     movu        m0, [r2+7]
2822     movu        m1, [r2+6]
2823     pavgb       m3, m2, m0              ; Gl6 Gl5 Gl4 Gl3 Gl2 Gl1 Gl0 Glt Gt0 Gt1 Gt2 Gt3 Gt4 Gt5 Gt6 Gt7
2824     PRED4x4_LOWPASS m0, m1, m2, m0, tmp ; Fl7 Fl6 Fl5 Fl4 Fl3 Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Ft6
2825     pshufb      m1, m0, [off(intra8x9_ddr1)]
2826     pshufb      m2, m0, [off(intra8x9_ddr2)]
2827     mova pred(4,0), m1
2828     psadbw      m1, fenc02
2829     mova pred(4,1), m2
2830     psadbw      m2, fenc13
2831     paddw       m1, m2
2832     pshufb      m2, m0, [off(intra8x9_ddr3)]
2833     mova pred(4,2), m2
2834     psadbw      m2, fenc46
2835     paddw       m1, m2
2836     pshufb      m2, m0, [off(intra8x9_ddr4)]
2837     mova pred(4,3), m2
2838     psadbw      m2, fenc57
2839     paddw       m1, m2
2840     movhlps     m2, m1
2841     paddw       m1, m2
2842     movd    [r4+8], m1
2843
2844     add         r0, 256
2845     add         r5, 0xC0
2846     %define off(m) (r0+m-(intra8x9_h1+256+128))
2847     %define pred(i,j) [r5+i*0x40+j*0x10-0x1C0]
2848
2849 ; vr
2850 ; Gt0 Gt1 Gt2 Gt3 Gt4 Gt5 Gt6 Gt7
2851 ; Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 Ft6
2852 ; Fl0 Gt0 Gt1 Gt2 Gt3 Gt4 Gt5 Gt6
2853 ; Fl1 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5
2854 ; Fl2 Fl0 Gt0 Gt1 Gt2 Gt3 Gt4 Gt5
2855 ; Fl3 Fl1 Flt Ft0 Ft1 Ft2 Ft3 Ft4
2856 ; Fl4 Fl2 Fl0 Gt0 Gt1 Gt2 Gt3 Gt4
2857 ; Fl5 Fl3 Fl1 Flt Ft0 Ft1 Ft2 Ft3
2858     movsd       m2, m3, m0 ; Fl7 Fl6 Fl5 Fl4 Fl3 Fl2 Fl1 Fl0 Gt0 Gt1 Gt2 Gt3 Gt4 Gt5 Gt6 Gt7
2859     pshufb      m1, m2, [off(intra8x9_vr1)]
2860     pshufb      m2, m2, [off(intra8x9_vr3)]
2861     mova pred(5,0), m1
2862     psadbw      m1, fenc02
2863     mova pred(5,2), m2
2864     psadbw      m2, fenc46
2865     paddw       m1, m2
2866     pshufb      m2, m0, [off(intra8x9_vr2)]
2867     mova pred(5,1), m2
2868     psadbw      m2, fenc13
2869     paddw       m1, m2
2870     pshufb      m2, m0, [off(intra8x9_vr4)]
2871     mova pred(5,3), m2
2872     psadbw      m2, fenc57
2873     paddw       m1, m2
2874     movhlps     m2, m1
2875     paddw       m1, m2
2876     movd   [r4+10], m1
2877
2878 ; hd
2879 ; Glt Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5
2880 ; Gl0 Fl0 Glt Flt Ft0 Ft1 Ft2 Ft3
2881 ; Gl1 Fl1 Gl0 Fl0 Glt Flt Ft0 Ft1
2882 ; Gl2 Fl2 Gl1 Fl1 Gl0 Fl0 Glt Flt
2883 ; Gl3 Fl3 Gl2 Fl2 Gl1 Fl1 Gl0 Fl0
2884 ; Gl4 Fl4 Gl3 Fl3 Gl2 Fl2 Gl1 Fl1
2885 ; Gl5 Fl5 Gl4 Fl4 Gl3 Fl3 Gl2 Fl2
2886 ; Gl6 Fl6 Gl5 Fl5 Gl4 Fl4 Gl3 Fl3
2887     pshufd      m2, m3, q0001
2888 %if cpuflag(sse4)
2889     pblendw     m2, m0, q3330 ; Gl2 Gl1 Gl0 Glt ___ Fl2 Fl1 Fl0 Flt Ft0 Ft1 Ft2 Ft3 Ft4 Ft5 ___
2890 %else
2891     movss       m1, m0, m2
2892     SWAP        1, 2
2893 %endif
2894     punpcklbw   m0, m3        ; Fl7 Gl6 Fl6 Gl5 Fl5 Gl4 Fl4 Gl3 Fl3 Gl2 Fl2 Gl1 Fl1 Gl0 Fl0 ___
2895     pshufb      m1, m2, [off(intra8x9_hd1)]
2896     pshufb      m2, m2, [off(intra8x9_hd2)]
2897     mova pred(6,0), m1
2898     psadbw      m1, fenc02
2899     mova pred(6,1), m2
2900     psadbw      m2, fenc13
2901     paddw       m1, m2
2902     pshufb      m2, m0, [off(intra8x9_hd3)]
2903     pshufb      m3, m0, [off(intra8x9_hd4)]
2904     mova pred(6,2), m2
2905     psadbw      m2, fenc46
2906     mova pred(6,3), m3
2907     psadbw      m3, fenc57
2908     paddw       m1, m2
2909     paddw       m1, m3
2910     movhlps     m2, m1
2911     paddw       m1, m2
2912     ; don't just store to [r4+12]. this is too close to the load of dqword [r4] and would cause a forwarding stall
2913     pslldq      m1, 12
2914     SWAP        3, 1
2915
2916 ; hu
2917 ; Gl0 Fl1 Gl1 Fl2 Gl2 Fl3 Gl3 Fl4
2918 ; Gl1 Fl2 Gl2 Fl3 Gl3 Fl4 Gl4 Fl5
2919 ; Gl2 Fl3 Gl3 Gl3 Gl4 Fl5 Gl5 Fl6
2920 ; Gl3 Gl3 Gl4 Fl5 Gl5 Fl6 Gl6 Fl7
2921 ; Gl4 Fl5 Gl5 Fl6 Gl6 Fl7 Gl7 Gl7
2922 ; Gl5 Fl6 Gl6 Fl7 Gl7 Gl7 Gl7 Gl7
2923 ; Gl6 Fl7 Gl7 Gl7 Gl7 Gl7 Gl7 Gl7
2924 ; Gl7 Gl7 Gl7 Gl7 Gl7 Gl7 Gl7 Gl7
2925 %if cpuflag(sse4)
2926     pinsrb      m0, [r2+7], 15 ; Gl7
2927 %else
2928     movd        m1, [r2+7]
2929     pslldq      m0, 1
2930     palignr     m1, m0, 1
2931     SWAP        0, 1
2932 %endif
2933     pshufb      m1, m0, [off(intra8x9_hu1)]
2934     pshufb      m2, m0, [off(intra8x9_hu2)]
2935     mova pred(8,0), m1
2936     psadbw      m1, fenc02
2937     mova pred(8,1), m2
2938     psadbw      m2, fenc13
2939     paddw       m1, m2
2940     pshufb      m2, m0, [off(intra8x9_hu3)]
2941     pshufb      m0, m0, [off(intra8x9_hu4)]
2942     mova pred(8,2), m2
2943     psadbw      m2, fenc46
2944     mova pred(8,3), m0
2945     psadbw      m0, fenc57
2946     paddw       m1, m2
2947     paddw       m1, m0
2948     movhlps     m2, m1
2949     paddw       m1, m2
2950     movd       r2d, m1
2951
2952     movu        m0, [r3]
2953     por         m3, [r4]
2954     paddw       m0, m3
2955     mova      [r4], m0
2956     movzx      r5d, word [r3+16]
2957     add        r2d, r5d
2958     mov    [r4+16], r2w
2959
2960 %if cpuflag(sse4)
2961     phminposuw m0, m0 ; v,h,dc,ddl,ddr,vr,hd,vl
2962     movd      eax, m0
2963 %else
2964     ; 8x8 sad is up to 14 bits; +bitcosts and saturate -> 14 bits; pack with 2 bit index
2965     paddusw    m0, m0
2966     paddusw    m0, m0
2967     paddw      m0, [off(pw_s00112233)]
2968     movhlps    m1, m0
2969     pminsw     m0, m1
2970     pshuflw    m1, m0, q0032
2971     pminsw     m0, m1
2972     movd      eax, m0
2973     ; repack with 3 bit index
2974     xor       eax, 0x80008000
2975     movzx     r3d, ax
2976     shr       eax, 15
2977     add       r3d, r3d
2978     or        eax, 1
2979     cmp       eax, r3d
2980     cmovg     eax, r3d
2981     ; reverse to phminposuw order
2982     mov       r3d, eax
2983     and       eax, 7
2984     shr       r3d, 3
2985     shl       eax, 16
2986     or        eax, r3d
2987 %endif
2988     add       r2d, 8<<16
2989     cmp        ax, r2w
2990     cmovg     eax, r2d
2991
2992     mov       r2d, eax
2993     shr       r2d, 16
2994     shl       r2d, 6
2995     add        r1, 4*FDEC_STRIDE
2996     mova       m0, [rsp+padbase+r2+0x00]
2997     mova       m1, [rsp+padbase+r2+0x10]
2998     mova       m2, [rsp+padbase+r2+0x20]
2999     mova       m3, [rsp+padbase+r2+0x30]
3000     movq   [r1+FDEC_STRIDE*-4], m0
3001     movhps [r1+FDEC_STRIDE*-2], m0
3002     movq   [r1+FDEC_STRIDE*-3], m1
3003     movhps [r1+FDEC_STRIDE*-1], m1
3004     movq   [r1+FDEC_STRIDE* 0], m2
3005     movhps [r1+FDEC_STRIDE* 2], m2
3006     movq   [r1+FDEC_STRIDE* 1], m3
3007     movhps [r1+FDEC_STRIDE* 3], m3
3008     ADD       rsp, pad
3009     RET
3010
3011 %ifdef ARCH_X86_64
3012 ;-----------------------------------------------------------------------------
3013 ; int intra_sa8d_x9_8x8( uint8_t *fenc, uint8_t *fdec, uint8_t edge[36], uint16_t *bitcosts, uint16_t *satds )
3014 ;-----------------------------------------------------------------------------
3015 cglobal intra_sa8d_x9_8x8, 5,6,16
3016     %assign pad 0x2c0+0x10-gprsize-(stack_offset&15)
3017     %define fenc_buf rsp
3018     %define pred_buf rsp+0x80
3019     SUB        rsp, pad
3020     mova       m15, [hmul_8p]
3021     pxor        m8, m8
3022 %assign %%i 0
3023 %rep 8
3024     movddup     m %+ %%i, [r0+%%i*FENC_STRIDE]
3025     pmaddubsw   m9, m %+ %%i, m15
3026     punpcklbw   m %+ %%i, m8
3027     mova [fenc_buf+%%i*0x10], m9
3028 %assign %%i %%i+1
3029 %endrep
3030
3031     ; save instruction size: avoid 4-byte memory offsets
3032     lea         r0, [intra8x9_h1+0x80]
3033     %define off(m) (r0+m-(intra8x9_h1+0x80))
3034     lea         r5, [pred_buf+0x80]
3035
3036 ; v, h, dc
3037     HADAMARD8_2D 0, 1, 2, 3, 4, 5, 6, 7, 8
3038     pabsw      m11, m1
3039 %assign %%i 2
3040 %rep 6
3041     pabsw       m8, m %+ %%i
3042     paddw      m11, m8
3043 %assign %%i %%i+1
3044 %endrep
3045
3046     ; 1D hadamard of edges
3047     movq        m8, [r2+7]
3048     movddup     m9, [r2+16]
3049     mova [r5-0x80], m9
3050     mova [r5-0x70], m9
3051     mova [r5-0x60], m9
3052     mova [r5-0x50], m9
3053     punpcklwd   m8, m8
3054     pshufb      m9, [intrax3_shuf]
3055     pmaddubsw   m8, [pb_pppm]
3056     pmaddubsw   m9, [pb_pppm]
3057     HSUMSUB2 psignw, m8, m9, m12, m13, m9, q1032, [pw_ppppmmmm]
3058     HSUMSUB2 psignw, m8, m9, m12, m13, m9, q2301, [pw_ppmmppmm]
3059
3060     ; dc
3061     paddw      m10, m8, m9
3062     paddw      m10, [pw_8]
3063     pand       m10, [sw_f0]
3064     psrlw      m12, m10, 4
3065     psllw      m10, 2
3066     pxor       m13, m13
3067     pshufb     m12, m13
3068     mova [r5+0x00], m12
3069     mova [r5+0x10], m12
3070     mova [r5+0x20], m12
3071     mova [r5+0x30], m12
3072
3073     ; differences
3074     psllw       m8, 3 ; left edge
3075     psubw       m8, m0
3076     psubw      m10, m0
3077     pabsw       m8, m8 ; 1x8 sum
3078     pabsw      m10, m10
3079     paddw       m8, m11
3080     paddw      m11, m10
3081     punpcklwd   m0, m1
3082     punpcklwd   m2, m3
3083     punpcklwd   m4, m5
3084     punpcklwd   m6, m7
3085     punpckldq   m0, m2
3086     punpckldq   m4, m6
3087     punpcklqdq  m0, m4 ; transpose
3088     psllw       m9, 3  ; top edge
3089     psrldq     m10, m11, 2 ; 8x7 sum
3090     psubw       m0, m9 ; 8x1 sum
3091     pabsw       m0, m0
3092     paddw      m10, m0
3093
3094     phaddd     m10, m8 ; logically phaddw, but this is faster and it won't overflow
3095     psrlw      m11, 1
3096     psrlw      m10, 1
3097
3098 ; store h
3099     movq        m3, [r2+7]
3100     pshufb      m0, m3, [off(intra8x9_h1)]
3101     pshufb      m1, m3, [off(intra8x9_h2)]
3102     pshufb      m2, m3, [off(intra8x9_h3)]
3103     pshufb      m3, m3, [off(intra8x9_h4)]
3104     mova [r5-0x40], m0
3105     mova [r5-0x30], m1
3106     mova [r5-0x20], m2
3107     mova [r5-0x10], m3
3108
3109 ; ddl
3110     mova        m8, [r2+16]
3111     movu        m2, [r2+17]
3112     pslldq      m1, m8, 1
3113     pavgb       m9, m8, m2
3114     PRED4x4_LOWPASS m8, m1, m2, m8, m3
3115     pshufb      m0, m8, [off(intra8x9_ddl1)]
3116     pshufb      m1, m8, [off(intra8x9_ddl2)]
3117     pshufb      m2, m8, [off(intra8x9_ddl3)]
3118     pshufb      m3, m8, [off(intra8x9_ddl4)]
3119     add         r5, 0x40
3120     call .sa8d
3121     phaddd     m11, m0
3122
3123 ; vl
3124     pshufb      m0, m9, [off(intra8x9_vl1)]
3125     pshufb      m1, m8, [off(intra8x9_vl2)]
3126     pshufb      m2, m9, [off(intra8x9_vl3)]
3127     pshufb      m3, m8, [off(intra8x9_vl4)]
3128     add         r5, 0x100
3129     call .sa8d
3130     phaddd     m10, m11
3131     mova       m12, m0
3132
3133 ; ddr
3134     movu        m2, [r2+8]
3135     movu        m8, [r2+7]
3136     movu        m1, [r2+6]
3137     pavgb       m9, m2, m8
3138     PRED4x4_LOWPASS m8, m1, m2, m8, m3
3139     pshufb      m0, m8, [off(intra8x9_ddr1)]
3140     pshufb      m1, m8, [off(intra8x9_ddr2)]
3141     pshufb      m2, m8, [off(intra8x9_ddr3)]
3142     pshufb      m3, m8, [off(intra8x9_ddr4)]
3143     sub         r5, 0xc0
3144     call .sa8d
3145     mova       m11, m0
3146
3147     add         r0, 0x100
3148     %define off(m) (r0+m-(intra8x9_h1+0x180))
3149
3150 ; vr
3151     movsd       m2, m9, m8
3152     pshufb      m0, m2, [off(intra8x9_vr1)]
3153     pshufb      m1, m8, [off(intra8x9_vr2)]
3154     pshufb      m2, m2, [off(intra8x9_vr3)]
3155     pshufb      m3, m8, [off(intra8x9_vr4)]
3156     add         r5, 0x40
3157     call .sa8d
3158     phaddd     m11, m0
3159
3160 ; hd
3161 %if cpuflag(sse4)
3162     pshufd      m1, m9, q0001
3163     pblendw     m1, m8, q3330
3164 %else
3165     pshufd      m2, m9, q0001
3166     movss       m1, m8, m2
3167 %endif
3168     punpcklbw   m8, m9
3169     pshufb      m0, m1, [off(intra8x9_hd1)]
3170     pshufb      m1, m1, [off(intra8x9_hd2)]
3171     pshufb      m2, m8, [off(intra8x9_hd3)]
3172     pshufb      m3, m8, [off(intra8x9_hd4)]
3173     add         r5, 0x40
3174     call .sa8d
3175     phaddd      m0, m12
3176     phaddd     m11, m0
3177
3178 ; hu
3179 %if cpuflag(sse4)
3180     pinsrb      m8, [r2+7], 15
3181 %else
3182     movd        m9, [r2+7]
3183     pslldq      m8, 1
3184     palignr     m9, m8, 1
3185     SWAP        8, 9
3186 %endif
3187     pshufb      m0, m8, [off(intra8x9_hu1)]
3188     pshufb      m1, m8, [off(intra8x9_hu2)]
3189     pshufb      m2, m8, [off(intra8x9_hu3)]
3190     pshufb      m3, m8, [off(intra8x9_hu4)]
3191     add         r5, 0x80
3192     call .sa8d
3193
3194     pmaddwd     m0, [pw_1]
3195     phaddw     m10, m11
3196     movhlps     m1, m0
3197     paddw       m0, m1
3198     pshuflw     m1, m0, q0032
3199     pavgw       m0, m1
3200     pxor        m2, m2
3201     pavgw      m10, m2
3202     movd       r2d, m0
3203
3204     movu        m0, [r3]
3205     paddw       m0, m10
3206     mova      [r4], m0
3207     movzx      r5d, word [r3+16]
3208     add        r2d, r5d
3209     mov    [r4+16], r2w
3210
3211 %if cpuflag(sse4)
3212     phminposuw m0, m0
3213     movd      eax, m0
3214 %else
3215     ; 8x8 sa8d is up to 15 bits; +bitcosts and saturate -> 15 bits; pack with 1 bit index
3216     paddusw    m0, m0
3217     paddw      m0, [off(pw_s00001111)]
3218     movhlps    m1, m0
3219     pminsw     m0, m1
3220     pshuflw    m1, m0, q0032
3221     mova       m2, m0
3222     pminsw     m0, m1
3223     pcmpgtw    m2, m1 ; 2nd index bit
3224     movd      r3d, m0
3225     movd      r4d, m2
3226     ; repack with 3 bit index
3227     xor       r3d, 0x80008000
3228     and       r4d, 0x00020002
3229     movzx     eax, r3w
3230     movzx     r5d, r4w
3231     shr       r3d, 16
3232     shr       r4d, 16
3233     lea       eax, [rax*4+r5]
3234     lea       r3d, [ r3*4+r4+1]
3235     cmp       eax, r3d
3236     cmovg     eax, r3d
3237     ; reverse to phminposuw order
3238     mov       r3d, eax
3239     and       eax, 7
3240     shr       r3d, 3
3241     shl       eax, 16
3242     or        eax, r3d
3243 %endif
3244     add       r2d, 8<<16
3245     cmp        ax, r2w
3246     cmovg     eax, r2d
3247
3248     mov       r2d, eax
3249     shr       r2d, 16
3250     shl       r2d, 6
3251     add        r1, 4*FDEC_STRIDE
3252     mova       m0, [pred_buf+r2+0x00]
3253     mova       m1, [pred_buf+r2+0x10]
3254     mova       m2, [pred_buf+r2+0x20]
3255     mova       m3, [pred_buf+r2+0x30]
3256     movq   [r1+FDEC_STRIDE*-4], m0
3257     movhps [r1+FDEC_STRIDE*-2], m0
3258     movq   [r1+FDEC_STRIDE*-3], m1
3259     movhps [r1+FDEC_STRIDE*-1], m1
3260     movq   [r1+FDEC_STRIDE* 0], m2
3261     movhps [r1+FDEC_STRIDE* 2], m2
3262     movq   [r1+FDEC_STRIDE* 1], m3
3263     movhps [r1+FDEC_STRIDE* 3], m3
3264     ADD       rsp, pad
3265     RET
3266
3267 ALIGN 16
3268 .sa8d:
3269     %xdefine mret m0
3270     %xdefine fenc_buf fenc_buf+gprsize
3271     mova [r5+0x00], m0
3272     mova [r5+0x10], m1
3273     mova [r5+0x20], m2
3274     mova [r5+0x30], m3
3275     movddup     m4, m0
3276     movddup     m5, m1
3277     movddup     m6, m2
3278     movddup     m7, m3
3279     punpckhqdq  m0, m0
3280     punpckhqdq  m1, m1
3281     punpckhqdq  m2, m2
3282     punpckhqdq  m3, m3
3283     PERMUTE 0,4, 1,5, 2,0, 3,1, 4,6, 5,7, 6,2, 7,3
3284     pmaddubsw   m0, m15
3285     pmaddubsw   m1, m15
3286     psubw       m0, [fenc_buf+0x00]
3287     psubw       m1, [fenc_buf+0x10]
3288     pmaddubsw   m2, m15
3289     pmaddubsw   m3, m15
3290     psubw       m2, [fenc_buf+0x20]
3291     psubw       m3, [fenc_buf+0x30]
3292     pmaddubsw   m4, m15
3293     pmaddubsw   m5, m15
3294     psubw       m4, [fenc_buf+0x40]
3295     psubw       m5, [fenc_buf+0x50]
3296     pmaddubsw   m6, m15
3297     pmaddubsw   m7, m15
3298     psubw       m6, [fenc_buf+0x60]
3299     psubw       m7, [fenc_buf+0x70]
3300     HADAMARD8_2D_HMUL 0, 1, 2, 3, 4, 5, 6, 7, 13, 14
3301     paddw       m0, m1
3302     paddw       m0, m2
3303     paddw mret, m0, m3
3304     ret
3305 %endif ; ARCH_X86_64
3306 %endmacro ; INTRA8_X9
3307
3308 ; in:  r0=pix, r1=stride, r2=stride*3, r3=tmp, m6=mask_ac4, m7=0
3309 ; out: [tmp]=hadamard4, m0=satd
3310 INIT_MMX mmx2
3311 cglobal hadamard_ac_4x4
3312 %ifdef HIGH_BIT_DEPTH
3313     mova      m0, [r0]
3314     mova      m1, [r0+r1]
3315     mova      m2, [r0+r1*2]
3316     mova      m3, [r0+r2]
3317 %else ; !HIGH_BIT_DEPTH
3318     movh      m0, [r0]
3319     movh      m1, [r0+r1]
3320     movh      m2, [r0+r1*2]
3321     movh      m3, [r0+r2]
3322     punpcklbw m0, m7
3323     punpcklbw m1, m7
3324     punpcklbw m2, m7
3325     punpcklbw m3, m7
3326 %endif ; HIGH_BIT_DEPTH
3327     HADAMARD4_2D 0, 1, 2, 3, 4
3328     mova [r3],    m0
3329     mova [r3+8],  m1
3330     mova [r3+16], m2
3331     mova [r3+24], m3
3332     ABSW      m0, m0, m4
3333     ABSW      m1, m1, m4
3334     pand      m0, m6
3335     ABSW      m2, m2, m4
3336     ABSW      m3, m3, m4
3337     paddw     m0, m1
3338     paddw     m2, m3
3339     paddw     m0, m2
3340     SAVE_MM_PERMUTATION
3341     ret
3342
3343 cglobal hadamard_ac_2x2max
3344     mova      m0, [r3+0x00]
3345     mova      m1, [r3+0x20]
3346     mova      m2, [r3+0x40]
3347     mova      m3, [r3+0x60]
3348     sub       r3, 8
3349     SUMSUB_BADC w, 0, 1, 2, 3, 4
3350     ABSW2 m0, m2, m0, m2, m4, m5
3351     ABSW2 m1, m3, m1, m3, m4, m5
3352     HADAMARD 0, max, 0, 2, 4, 5
3353     HADAMARD 0, max, 1, 3, 4, 5
3354 %ifdef HIGH_BIT_DEPTH
3355     pmaddwd   m0, m7
3356     pmaddwd   m1, m7
3357     paddd     m6, m0
3358     paddd     m6, m1
3359 %else ; !HIGH_BIT_DEPTH
3360     paddw     m7, m0
3361     paddw     m7, m1
3362 %endif ; HIGH_BIT_DEPTH
3363     SAVE_MM_PERMUTATION
3364     ret
3365
3366 %macro AC_PREP 2
3367 %ifdef HIGH_BIT_DEPTH
3368     pmaddwd %1, %2
3369 %endif
3370 %endmacro
3371
3372 %macro AC_PADD 3
3373 %ifdef HIGH_BIT_DEPTH
3374     AC_PREP %2, %3
3375     paddd   %1, %2
3376 %else
3377     paddw   %1, %2
3378 %endif ; HIGH_BIT_DEPTH
3379 %endmacro
3380
3381 cglobal hadamard_ac_8x8
3382     mova      m6, [mask_ac4]
3383 %ifdef HIGH_BIT_DEPTH
3384     mova      m7, [pw_1]
3385 %else
3386     pxor      m7, m7
3387 %endif ; HIGH_BIT_DEPTH
3388     call hadamard_ac_4x4_mmx2
3389     add       r0, 4*SIZEOF_PIXEL
3390     add       r3, 32
3391     mova      m5, m0
3392     AC_PREP   m5, m7
3393     call hadamard_ac_4x4_mmx2
3394     lea       r0, [r0+4*r1]
3395     add       r3, 64
3396     AC_PADD   m5, m0, m7
3397     call hadamard_ac_4x4_mmx2
3398     sub       r0, 4*SIZEOF_PIXEL
3399     sub       r3, 32
3400     AC_PADD   m5, m0, m7
3401     call hadamard_ac_4x4_mmx2
3402     AC_PADD   m5, m0, m7
3403     sub       r3, 40
3404     mova [rsp+gprsize+8], m5 ; save satd
3405 %ifdef HIGH_BIT_DEPTH
3406     pxor      m6, m6
3407 %endif
3408 %rep 3
3409     call hadamard_ac_2x2max_mmx2
3410 %endrep
3411     mova      m0, [r3+0x00]
3412     mova      m1, [r3+0x20]
3413     mova      m2, [r3+0x40]
3414     mova      m3, [r3+0x60]
3415     SUMSUB_BADC w, 0, 1, 2, 3, 4
3416     HADAMARD 0, sumsub, 0, 2, 4, 5
3417     ABSW2 m1, m3, m1, m3, m4, m5
3418     ABSW2 m0, m2, m0, m2, m4, m5
3419     HADAMARD 0, max, 1, 3, 4, 5
3420 %ifdef HIGH_BIT_DEPTH
3421     pand      m0, [mask_ac4]
3422     pmaddwd   m1, m7
3423     pmaddwd   m0, m7
3424     pmaddwd   m2, m7
3425     paddd     m6, m1
3426     paddd     m0, m2
3427     paddd     m6, m6
3428     paddd     m0, m6
3429     SWAP       0,  6
3430 %else ; !HIGH_BIT_DEPTH
3431     pand      m6, m0
3432     paddw     m7, m1
3433     paddw     m6, m2
3434     paddw     m7, m7
3435     paddw     m6, m7
3436 %endif ; HIGH_BIT_DEPTH
3437     mova [rsp+gprsize], m6 ; save sa8d
3438     SWAP       0,  6
3439     SAVE_MM_PERMUTATION
3440     ret
3441
3442 %macro HADAMARD_AC_WXH_SUM_MMX 2
3443     mova    m1, [rsp+1*mmsize]
3444 %ifdef HIGH_BIT_DEPTH
3445 %if %1*%2 >= 128
3446     paddd   m0, [rsp+2*mmsize]
3447     paddd   m1, [rsp+3*mmsize]
3448 %endif
3449 %if %1*%2 == 256
3450     mova    m2, [rsp+4*mmsize]
3451     paddd   m1, [rsp+5*mmsize]
3452     paddd   m2, [rsp+6*mmsize]
3453     mova    m3, m0
3454     paddd   m1, [rsp+7*mmsize]
3455     paddd   m0, m2
3456 %endif
3457     psrld   m0, 1
3458     HADDD   m0, m2
3459     psrld   m1, 1
3460     HADDD   m1, m3
3461 %else ; !HIGH_BIT_DEPTH
3462 %if %1*%2 >= 128
3463     paddusw m0, [rsp+2*mmsize]
3464     paddusw m1, [rsp+3*mmsize]
3465 %endif
3466 %if %1*%2 == 256
3467     mova    m2, [rsp+4*mmsize]
3468     paddusw m1, [rsp+5*mmsize]
3469     paddusw m2, [rsp+6*mmsize]
3470     mova    m3, m0
3471     paddusw m1, [rsp+7*mmsize]
3472     pxor    m3, m2
3473     pand    m3, [pw_1]
3474     pavgw   m0, m2
3475     psubusw m0, m3
3476     HADDUW  m0, m2
3477 %else
3478     psrlw   m0, 1
3479     HADDW   m0, m2
3480 %endif
3481     psrlw   m1, 1
3482     HADDW   m1, m3
3483 %endif ; HIGH_BIT_DEPTH
3484 %endmacro
3485
3486 %macro HADAMARD_AC_WXH_MMX 2
3487 cglobal pixel_hadamard_ac_%1x%2, 2,4
3488     %assign pad 16-gprsize-(stack_offset&15)
3489     %define ysub r1
3490     FIX_STRIDES r1
3491     sub  rsp, 16+128+pad
3492     lea  r2, [r1*3]
3493     lea  r3, [rsp+16]
3494     call hadamard_ac_8x8_mmx2
3495 %if %2==16
3496     %define ysub r2
3497     lea  r0, [r0+r1*4]
3498     sub  rsp, 16
3499     call hadamard_ac_8x8_mmx2
3500 %endif
3501 %if %1==16
3502     neg  ysub
3503     sub  rsp, 16
3504     lea  r0, [r0+ysub*4+8*SIZEOF_PIXEL]
3505     neg  ysub
3506     call hadamard_ac_8x8_mmx2
3507 %if %2==16
3508     lea  r0, [r0+r1*4]
3509     sub  rsp, 16
3510     call hadamard_ac_8x8_mmx2
3511 %endif
3512 %endif
3513     HADAMARD_AC_WXH_SUM_MMX %1, %2
3514     movd edx, m0
3515     movd eax, m1
3516     shr  edx, 1
3517 %ifdef ARCH_X86_64
3518     shl  rdx, 32
3519     add  rax, rdx
3520 %endif
3521     add  rsp, 128+%1*%2/4+pad
3522     RET
3523 %endmacro ; HADAMARD_AC_WXH_MMX
3524
3525 HADAMARD_AC_WXH_MMX 16, 16
3526 HADAMARD_AC_WXH_MMX  8, 16
3527 HADAMARD_AC_WXH_MMX 16,  8
3528 HADAMARD_AC_WXH_MMX  8,  8
3529
3530 %macro LOAD_INC_8x4W_SSE2 5
3531 %ifdef HIGH_BIT_DEPTH
3532     movu      m%1, [r0]
3533     movu      m%2, [r0+r1]
3534     movu      m%3, [r0+r1*2]
3535     movu      m%4, [r0+r2]
3536 %ifidn %1, 0
3537     lea       r0, [r0+r1*4]
3538 %endif
3539 %else ; !HIGH_BIT_DEPTH
3540     movh      m%1, [r0]
3541     movh      m%2, [r0+r1]
3542     movh      m%3, [r0+r1*2]
3543     movh      m%4, [r0+r2]
3544 %ifidn %1, 0
3545     lea       r0, [r0+r1*4]
3546 %endif
3547     punpcklbw m%1, m%5
3548     punpcklbw m%2, m%5
3549     punpcklbw m%3, m%5
3550     punpcklbw m%4, m%5
3551 %endif ; HIGH_BIT_DEPTH
3552 %endmacro
3553
3554 %macro LOAD_INC_8x4W_SSSE3 5
3555     LOAD_DUP_4x8P %3, %4, %1, %2, [r0+r1*2], [r0+r2], [r0], [r0+r1]
3556 %ifidn %1, 0
3557     lea       r0, [r0+r1*4]
3558 %endif
3559     HSUMSUB %1, %2, %3, %4, %5
3560 %endmacro
3561
3562 %macro HADAMARD_AC_SSE2 0
3563 ; in:  r0=pix, r1=stride, r2=stride*3
3564 ; out: [esp+16]=sa8d, [esp+32]=satd, r0+=stride*4
3565 cglobal hadamard_ac_8x8
3566 %ifdef ARCH_X86_64
3567     %define spill0 m8
3568     %define spill1 m9
3569     %define spill2 m10
3570 %else
3571     %define spill0 [rsp+gprsize]
3572     %define spill1 [rsp+gprsize+16]
3573     %define spill2 [rsp+gprsize+32]
3574 %endif
3575 %ifdef HIGH_BIT_DEPTH
3576     %define vertical 1
3577 %elif cpuflag(ssse3)
3578     %define vertical 0
3579     ;LOAD_INC loads sumsubs
3580     mova      m7, [hmul_8p]
3581 %else
3582     %define vertical 1
3583     ;LOAD_INC only unpacks to words
3584     pxor      m7, m7
3585 %endif
3586     LOAD_INC_8x4W 0, 1, 2, 3, 7
3587 %if vertical
3588     HADAMARD4_2D_SSE 0, 1, 2, 3, 4
3589 %else
3590     HADAMARD4_V 0, 1, 2, 3, 4
3591 %endif
3592     mova  spill0, m1
3593     SWAP 1, 7
3594     LOAD_INC_8x4W 4, 5, 6, 7, 1
3595 %if vertical
3596     HADAMARD4_2D_SSE 4, 5, 6, 7, 1
3597 %else
3598     HADAMARD4_V 4, 5, 6, 7, 1
3599     ; FIXME SWAP
3600     mova      m1, spill0
3601     mova      spill0, m6
3602     mova      spill1, m7
3603     HADAMARD 1, sumsub, 0, 1, 6, 7
3604     HADAMARD 1, sumsub, 2, 3, 6, 7
3605     mova      m6, spill0
3606     mova      m7, spill1
3607     mova      spill0, m1
3608     mova      spill1, m0
3609     HADAMARD 1, sumsub, 4, 5, 1, 0
3610     HADAMARD 1, sumsub, 6, 7, 1, 0
3611     mova      m0, spill1
3612 %endif
3613     mova  spill1, m2
3614     mova  spill2, m3
3615     ABSW      m1, m0, m0
3616     ABSW      m2, m4, m4
3617     ABSW      m3, m5, m5
3618     paddw     m1, m2
3619     SUMSUB_BA w, 0, 4
3620 %if vertical
3621     pand      m1, [mask_ac4]
3622 %else
3623     pand      m1, [mask_ac4b]
3624 %endif
3625     AC_PREP   m1, [pw_1]
3626     ABSW      m2, spill0
3627     AC_PADD   m1, m3, [pw_1]
3628     ABSW      m3, spill1
3629     AC_PADD   m1, m2, [pw_1]
3630     ABSW      m2, spill2
3631     AC_PADD   m1, m3, [pw_1]
3632     ABSW      m3, m6, m6
3633     AC_PADD   m1, m2, [pw_1]
3634     ABSW      m2, m7, m7
3635     AC_PADD   m1, m3, [pw_1]
3636     mova      m3, m7
3637     AC_PADD   m1, m2, [pw_1]
3638     mova      m2, m6
3639     psubw     m7, spill2
3640     paddw     m3, spill2
3641     mova  [rsp+gprsize+32], m1 ; save satd
3642     mova      m1, m5
3643     psubw     m6, spill1
3644     paddw     m2, spill1
3645     psubw     m5, spill0
3646     paddw     m1, spill0
3647     %assign %%x 2
3648 %if vertical
3649     %assign %%x 4
3650 %endif
3651     mova  spill1, m4
3652     HADAMARD %%x, amax, 3, 7, 4
3653     HADAMARD %%x, amax, 2, 6, 7, 4
3654     mova      m4, spill1
3655     HADAMARD %%x, amax, 1, 5, 6, 7
3656     HADAMARD %%x, sumsub, 0, 4, 5, 6
3657     AC_PREP   m2, [pw_1]
3658     AC_PADD   m2, m3, [pw_1]
3659     AC_PADD   m2, m1, [pw_1]
3660 %ifdef HIGH_BIT_DEPTH
3661     paddd     m2, m2
3662 %else
3663     paddw     m2, m2
3664 %endif ; HIGH_BIT_DEPTH
3665     ABSW      m4, m4, m7
3666     pand      m0, [mask_ac8]
3667     ABSW      m0, m0, m7
3668     AC_PADD   m2, m4, [pw_1]
3669     AC_PADD   m2, m0, [pw_1]
3670     mova [rsp+gprsize+16], m2 ; save sa8d
3671     SWAP       0, 2
3672     SAVE_MM_PERMUTATION
3673     ret
3674
3675 HADAMARD_AC_WXH_SSE2 16, 16
3676 HADAMARD_AC_WXH_SSE2  8, 16
3677 HADAMARD_AC_WXH_SSE2 16,  8
3678 HADAMARD_AC_WXH_SSE2  8,  8
3679 %endmacro ; HADAMARD_AC_SSE2
3680
3681 %macro HADAMARD_AC_WXH_SUM_SSE2 2
3682     mova    m1, [rsp+2*mmsize]
3683 %ifdef HIGH_BIT_DEPTH
3684 %if %1*%2 >= 128
3685     paddd   m0, [rsp+3*mmsize]
3686     paddd   m1, [rsp+4*mmsize]
3687 %endif
3688 %if %1*%2 == 256
3689     paddd   m0, [rsp+5*mmsize]
3690     paddd   m1, [rsp+6*mmsize]
3691     paddd   m0, [rsp+7*mmsize]
3692     paddd   m1, [rsp+8*mmsize]
3693     psrld   m0, 1
3694 %endif
3695     HADDD   m0, m2
3696     HADDD   m1, m3
3697 %else ; !HIGH_BIT_DEPTH
3698 %if %1*%2 >= 128
3699     paddusw m0, [rsp+3*mmsize]
3700     paddusw m1, [rsp+4*mmsize]
3701 %endif
3702 %if %1*%2 == 256
3703     paddusw m0, [rsp+5*mmsize]
3704     paddusw m1, [rsp+6*mmsize]
3705     paddusw m0, [rsp+7*mmsize]
3706     paddusw m1, [rsp+8*mmsize]
3707     psrlw   m0, 1
3708 %endif
3709     HADDUW  m0, m2
3710     HADDW   m1, m3
3711 %endif ; HIGH_BIT_DEPTH
3712 %endmacro
3713
3714 ; struct { int satd, int sa8d; } pixel_hadamard_ac_16x16( uint8_t *pix, int stride )
3715 %macro HADAMARD_AC_WXH_SSE2 2
3716 cglobal pixel_hadamard_ac_%1x%2, 2,3,11
3717     %assign pad 16-gprsize-(stack_offset&15)
3718     %define ysub r1
3719     FIX_STRIDES r1
3720     sub  rsp, 48+pad
3721     lea  r2, [r1*3]
3722     call hadamard_ac_8x8
3723 %if %2==16
3724     %define ysub r2
3725     lea  r0, [r0+r1*4]
3726     sub  rsp, 32
3727     call hadamard_ac_8x8
3728 %endif
3729 %if %1==16
3730     neg  ysub
3731     sub  rsp, 32
3732     lea  r0, [r0+ysub*4+8*SIZEOF_PIXEL]
3733     neg  ysub
3734     call hadamard_ac_8x8
3735 %if %2==16
3736     lea  r0, [r0+r1*4]
3737     sub  rsp, 32
3738     call hadamard_ac_8x8
3739 %endif
3740 %endif
3741     HADAMARD_AC_WXH_SUM_SSE2 %1, %2
3742     movd edx, m0
3743     movd eax, m1
3744     shr  edx, 2 - (%1*%2 >> 8)
3745     shr  eax, 1
3746 %ifdef ARCH_X86_64
3747     shl  rdx, 32
3748     add  rax, rdx
3749 %endif
3750     add  rsp, 16+%1*%2/2+pad
3751     RET
3752 %endmacro ; HADAMARD_AC_WXH_SSE2
3753
3754 ; instantiate satds
3755
3756 %ifndef ARCH_X86_64
3757 cextern pixel_sa8d_8x8_internal_mmx2
3758 INIT_MMX mmx2
3759 SA8D
3760 %endif
3761
3762 %define TRANS TRANS_SSE2
3763 %define DIFFOP DIFF_UNPACK_SSE2
3764 %define LOAD_INC_8x4W LOAD_INC_8x4W_SSE2
3765 %define LOAD_SUMSUB_8x4P LOAD_DIFF_8x4P
3766 %define LOAD_SUMSUB_16P  LOAD_SUMSUB_16P_SSE2
3767 %define movdqa movaps ; doesn't hurt pre-nehalem, might as well save size
3768 %define movdqu movups
3769 %define punpcklqdq movlhps
3770 INIT_XMM sse2
3771 SA8D
3772 SATDS_SSE2
3773 %ifndef HIGH_BIT_DEPTH
3774 INTRA_SA8D_SSE2
3775 %endif
3776 INIT_MMX mmx2
3777 INTRA_X3_MMX
3778 INIT_XMM sse2
3779 HADAMARD_AC_SSE2
3780
3781 %define DIFFOP DIFF_SUMSUB_SSSE3
3782 %define LOAD_DUP_4x8P LOAD_DUP_4x8P_CONROE
3783 %ifndef HIGH_BIT_DEPTH
3784 %define LOAD_INC_8x4W LOAD_INC_8x4W_SSSE3
3785 %define LOAD_SUMSUB_8x4P LOAD_SUMSUB_8x4P_SSSE3
3786 %define LOAD_SUMSUB_16P  LOAD_SUMSUB_16P_SSSE3
3787 %endif
3788 INIT_XMM ssse3
3789 SATDS_SSE2
3790 SA8D
3791 HADAMARD_AC_SSE2
3792 %ifndef HIGH_BIT_DEPTH
3793 INTRA_X9
3794 INTRA8_X9
3795 %endif
3796 %undef movdqa ; nehalem doesn't like movaps
3797 %undef movdqu ; movups
3798 %undef punpcklqdq ; or movlhps
3799 %ifndef HIGH_BIT_DEPTH
3800 INIT_MMX ssse3
3801 INTRA_X3_MMX
3802 %endif
3803
3804 %define TRANS TRANS_SSE4
3805 %define LOAD_DUP_4x8P LOAD_DUP_4x8P_PENRYN
3806 INIT_XMM sse4
3807 SATDS_SSE2
3808 SA8D
3809 HADAMARD_AC_SSE2
3810 %ifndef HIGH_BIT_DEPTH
3811 INTRA_X9
3812 INTRA8_X9
3813 %endif
3814
3815 INIT_XMM avx
3816 SATDS_SSE2
3817 SA8D
3818 %ifndef HIGH_BIT_DEPTH
3819 INTRA_X9
3820 INTRA8_X9
3821 %endif
3822 HADAMARD_AC_SSE2
3823
3824 %define TRANS TRANS_XOP
3825 INIT_XMM xop
3826 SATDS_SSE2
3827 SA8D
3828 %ifndef HIGH_BIT_DEPTH
3829 INTRA_X9
3830 ; no xop INTRA8_X9. it's slower than avx on bulldozer. dunno why.
3831 %endif
3832 HADAMARD_AC_SSE2
3833
3834 ;=============================================================================
3835 ; SSIM
3836 ;=============================================================================
3837
3838 ;-----------------------------------------------------------------------------
3839 ; void pixel_ssim_4x4x2_core( const uint8_t *pix1, int stride1,
3840 ;                             const uint8_t *pix2, int stride2, int sums[2][4] )
3841 ;-----------------------------------------------------------------------------
3842 %macro SSIM_ITER 1
3843 %ifdef HIGH_BIT_DEPTH
3844     movdqu    m5, [r0+(%1&1)*r1]
3845     movdqu    m6, [r2+(%1&1)*r3]
3846 %else
3847     movq      m5, [r0+(%1&1)*r1]
3848     movq      m6, [r2+(%1&1)*r3]
3849     punpcklbw m5, m0
3850     punpcklbw m6, m0
3851 %endif
3852 %if %1==1
3853     lea       r0, [r0+r1*2]
3854     lea       r2, [r2+r3*2]
3855 %endif
3856 %if %1==0
3857     movdqa    m1, m5
3858     movdqa    m2, m6
3859 %else
3860     paddw     m1, m5
3861     paddw     m2, m6
3862 %endif
3863     pmaddwd   m7, m5, m6
3864     pmaddwd   m5, m5
3865     pmaddwd   m6, m6
3866     ACCUM  paddd, 3, 5, %1
3867     ACCUM  paddd, 4, 7, %1
3868     paddd     m3, m6
3869 %endmacro
3870
3871 %macro SSIM 0
3872 cglobal pixel_ssim_4x4x2_core, 4,4,8
3873     FIX_STRIDES r1, r3
3874     pxor      m0, m0
3875     SSIM_ITER 0
3876     SSIM_ITER 1
3877     SSIM_ITER 2
3878     SSIM_ITER 3
3879     ; PHADDW m1, m2
3880     ; PHADDD m3, m4
3881     movdqa    m7, [pw_1]
3882     pshufd    m5, m3, q2301
3883     pmaddwd   m1, m7
3884     pmaddwd   m2, m7
3885     pshufd    m6, m4, q2301
3886     packssdw  m1, m2
3887     paddd     m3, m5
3888     pshufd    m1, m1, q3120
3889     paddd     m4, m6
3890     pmaddwd   m1, m7
3891     punpckhdq m5, m3, m4
3892     punpckldq m3, m4
3893
3894 %ifdef UNIX64
3895     %define t0 r4
3896 %else
3897     %define t0 rax
3898     mov t0, r4mp
3899 %endif
3900
3901     movq      [t0+ 0], m1
3902     movq      [t0+ 8], m3
3903     movhps    [t0+16], m1
3904     movq      [t0+24], m5
3905     RET
3906
3907 ;-----------------------------------------------------------------------------
3908 ; float pixel_ssim_end( int sum0[5][4], int sum1[5][4], int width )
3909 ;-----------------------------------------------------------------------------
3910 cglobal pixel_ssim_end4, 3,3,7
3911     movdqa    m0, [r0+ 0]
3912     movdqa    m1, [r0+16]
3913     movdqa    m2, [r0+32]
3914     movdqa    m3, [r0+48]
3915     movdqa    m4, [r0+64]
3916     paddd     m0, [r1+ 0]
3917     paddd     m1, [r1+16]
3918     paddd     m2, [r1+32]
3919     paddd     m3, [r1+48]
3920     paddd     m4, [r1+64]
3921     paddd     m0, m1
3922     paddd     m1, m2
3923     paddd     m2, m3
3924     paddd     m3, m4
3925     movdqa    m5, [ssim_c1]
3926     movdqa    m6, [ssim_c2]
3927     TRANSPOSE4x4D  0, 1, 2, 3, 4
3928
3929 ;   s1=m0, s2=m1, ss=m2, s12=m3
3930 %if BIT_DEPTH == 10
3931     cvtdq2ps  m0, m0
3932     cvtdq2ps  m1, m1
3933     cvtdq2ps  m2, m2
3934     cvtdq2ps  m3, m3
3935     mulps     m2, [pf_64] ; ss*64
3936     mulps     m3, [pf_128] ; s12*128
3937     movdqa    m4, m1
3938     mulps     m4, m0      ; s1*s2
3939     mulps     m1, m1      ; s2*s2
3940     mulps     m0, m0      ; s1*s1
3941     addps     m4, m4      ; s1*s2*2
3942     addps     m0, m1      ; s1*s1 + s2*s2
3943     subps     m2, m0      ; vars
3944     subps     m3, m4      ; covar*2
3945     addps     m4, m5      ; s1*s2*2 + ssim_c1
3946     addps     m0, m5      ; s1*s1 + s2*s2 + ssim_c1
3947     addps     m2, m6      ; vars + ssim_c2
3948     addps     m3, m6      ; covar*2 + ssim_c2
3949 %else
3950     pmaddwd   m4, m1, m0  ; s1*s2
3951     pslld     m1, 16
3952     por       m0, m1
3953     pmaddwd   m0, m0  ; s1*s1 + s2*s2
3954     pslld     m4, 1
3955     pslld     m3, 7
3956     pslld     m2, 6
3957     psubd     m3, m4  ; covar*2
3958     psubd     m2, m0  ; vars
3959     paddd     m0, m5
3960     paddd     m4, m5
3961     paddd     m3, m6
3962     paddd     m2, m6
3963     cvtdq2ps  m0, m0  ; (float)(s1*s1 + s2*s2 + ssim_c1)
3964     cvtdq2ps  m4, m4  ; (float)(s1*s2*2 + ssim_c1)
3965     cvtdq2ps  m3, m3  ; (float)(covar*2 + ssim_c2)
3966     cvtdq2ps  m2, m2  ; (float)(vars + ssim_c2)
3967 %endif
3968     mulps     m4, m3
3969     mulps     m0, m2
3970     divps     m4, m0  ; ssim
3971
3972     cmp       r2d, 4
3973     je .skip ; faster only if this is the common case; remove branch if we use ssim on a macroblock level
3974     neg       r2
3975 %ifdef PIC
3976     lea       r3, [mask_ff + 16]
3977     movdqu    m1, [r3 + r2*4]
3978 %else
3979     movdqu    m1, [mask_ff + r2*4 + 16]
3980 %endif
3981     pand      m4, m1
3982 .skip:
3983     movhlps   m0, m4
3984     addps     m0, m4
3985     pshuflw   m4, m0, q0032
3986     addss     m0, m4
3987 %ifndef ARCH_X86_64
3988     movd     r0m, m0
3989     fld     dword r0m
3990 %endif
3991     RET
3992 %endmacro ; SSIM
3993
3994 INIT_XMM sse2
3995 SSIM
3996 INIT_XMM avx
3997 SSIM
3998
3999 ;=============================================================================
4000 ; Successive Elimination ADS
4001 ;=============================================================================
4002
4003 %macro ADS_START 0
4004 %ifdef WIN64
4005     movsxd  r5,  r5d
4006 %endif
4007     mov     r0d, r5d
4008     lea     r6,  [r4+r5+15]
4009     and     r6,  ~15;
4010     shl     r2d,  1
4011 %endmacro
4012
4013 %macro ADS_END 1 ; unroll_size
4014     add     r1, 8*%1
4015     add     r3, 8*%1
4016     add     r6, 4*%1
4017     sub     r0d, 4*%1
4018     jg .loop
4019     WIN64_RESTORE_XMM rsp
4020     jmp ads_mvs
4021 %endmacro
4022
4023 ;-----------------------------------------------------------------------------
4024 ; int pixel_ads4( int enc_dc[4], uint16_t *sums, int delta,
4025 ;                 uint16_t *cost_mvx, int16_t *mvs, int width, int thresh )
4026 ;-----------------------------------------------------------------------------
4027 INIT_MMX mmx2
4028 cglobal pixel_ads4, 6,7
4029     movq    mm6, [r0]
4030     movq    mm4, [r0+8]
4031     pshufw  mm7, mm6, 0
4032     pshufw  mm6, mm6, q2222
4033     pshufw  mm5, mm4, 0
4034     pshufw  mm4, mm4, q2222
4035     ADS_START
4036 .loop:
4037     movq    mm0, [r1]
4038     movq    mm1, [r1+16]
4039     psubw   mm0, mm7
4040     psubw   mm1, mm6
4041     ABSW    mm0, mm0, mm2
4042     ABSW    mm1, mm1, mm3
4043     movq    mm2, [r1+r2]
4044     movq    mm3, [r1+r2+16]
4045     psubw   mm2, mm5
4046     psubw   mm3, mm4
4047     paddw   mm0, mm1
4048     ABSW    mm2, mm2, mm1
4049     ABSW    mm3, mm3, mm1
4050     paddw   mm0, mm2
4051     paddw   mm0, mm3
4052     pshufw  mm1, r6m, 0
4053     paddusw mm0, [r3]
4054     psubusw mm1, mm0
4055     packsswb mm1, mm1
4056     movd    [r6], mm1
4057     ADS_END 1
4058
4059 cglobal pixel_ads2, 6,7
4060     movq    mm6, [r0]
4061     pshufw  mm5, r6m, 0
4062     pshufw  mm7, mm6, 0
4063     pshufw  mm6, mm6, q2222
4064     ADS_START
4065 .loop:
4066     movq    mm0, [r1]
4067     movq    mm1, [r1+r2]
4068     psubw   mm0, mm7
4069     psubw   mm1, mm6
4070     ABSW    mm0, mm0, mm2
4071     ABSW    mm1, mm1, mm3
4072     paddw   mm0, mm1
4073     paddusw mm0, [r3]
4074     movq    mm4, mm5
4075     psubusw mm4, mm0
4076     packsswb mm4, mm4
4077     movd    [r6], mm4
4078     ADS_END 1
4079
4080 cglobal pixel_ads1, 6,7
4081     pshufw  mm7, [r0], 0
4082     pshufw  mm6, r6m, 0
4083     ADS_START
4084 .loop:
4085     movq    mm0, [r1]
4086     movq    mm1, [r1+8]
4087     psubw   mm0, mm7
4088     psubw   mm1, mm7
4089     ABSW    mm0, mm0, mm2
4090     ABSW    mm1, mm1, mm3
4091     paddusw mm0, [r3]
4092     paddusw mm1, [r3+8]
4093     movq    mm4, mm6
4094     movq    mm5, mm6
4095     psubusw mm4, mm0
4096     psubusw mm5, mm1
4097     packsswb mm4, mm5
4098     movq    [r6], mm4
4099     ADS_END 2
4100
4101 %macro ADS_XMM 0
4102 cglobal pixel_ads4, 6,7,12
4103     movdqa  xmm4, [r0]
4104     pshuflw xmm7, xmm4, 0
4105     pshuflw xmm6, xmm4, q2222
4106     pshufhw xmm5, xmm4, 0
4107     pshufhw xmm4, xmm4, q2222
4108     punpcklqdq xmm7, xmm7
4109     punpcklqdq xmm6, xmm6
4110     punpckhqdq xmm5, xmm5
4111     punpckhqdq xmm4, xmm4
4112 %ifdef ARCH_X86_64
4113     pshuflw xmm8, r6m, 0
4114     punpcklqdq xmm8, xmm8
4115     ADS_START
4116     movdqu  xmm10, [r1]
4117     movdqu  xmm11, [r1+r2]
4118 .loop:
4119     psubw   xmm0, xmm10, xmm7
4120     movdqu xmm10, [r1+16]
4121     psubw   xmm1, xmm10, xmm6
4122     ABSW    xmm0, xmm0, xmm2
4123     ABSW    xmm1, xmm1, xmm3
4124     psubw   xmm2, xmm11, xmm5
4125     movdqu xmm11, [r1+r2+16]
4126     paddw   xmm0, xmm1
4127     psubw   xmm3, xmm11, xmm4
4128     movdqu  xmm9, [r3]
4129     ABSW    xmm2, xmm2, xmm1
4130     ABSW    xmm3, xmm3, xmm1
4131     paddw   xmm0, xmm2
4132     paddw   xmm0, xmm3
4133     paddusw xmm0, xmm9
4134     psubusw xmm1, xmm8, xmm0
4135     packsswb xmm1, xmm1
4136     movq    [r6], xmm1
4137 %else
4138     ADS_START
4139 .loop:
4140     movdqu  xmm0, [r1]
4141     movdqu  xmm1, [r1+16]
4142     psubw   xmm0, xmm7
4143     psubw   xmm1, xmm6
4144     ABSW    xmm0, xmm0, xmm2
4145     ABSW    xmm1, xmm1, xmm3
4146     movdqu  xmm2, [r1+r2]
4147     movdqu  xmm3, [r1+r2+16]
4148     psubw   xmm2, xmm5
4149     psubw   xmm3, xmm4
4150     paddw   xmm0, xmm1
4151     ABSW    xmm2, xmm2, xmm1
4152     ABSW    xmm3, xmm3, xmm1
4153     paddw   xmm0, xmm2
4154     paddw   xmm0, xmm3
4155     movd    xmm1, r6m
4156     movdqu  xmm2, [r3]
4157     pshuflw xmm1, xmm1, 0
4158     punpcklqdq xmm1, xmm1
4159     paddusw xmm0, xmm2
4160     psubusw xmm1, xmm0
4161     packsswb xmm1, xmm1
4162     movq    [r6], xmm1
4163 %endif ; ARCH
4164     ADS_END 2
4165
4166 cglobal pixel_ads2, 6,7,8
4167     movq    xmm6, [r0]
4168     movd    xmm5, r6m
4169     pshuflw xmm7, xmm6, 0
4170     pshuflw xmm6, xmm6, q2222
4171     pshuflw xmm5, xmm5, 0
4172     punpcklqdq xmm7, xmm7
4173     punpcklqdq xmm6, xmm6
4174     punpcklqdq xmm5, xmm5
4175     ADS_START
4176 .loop:
4177     movdqu  xmm0, [r1]
4178     movdqu  xmm1, [r1+r2]
4179     psubw   xmm0, xmm7
4180     psubw   xmm1, xmm6
4181     movdqu  xmm4, [r3]
4182     ABSW    xmm0, xmm0, xmm2
4183     ABSW    xmm1, xmm1, xmm3
4184     paddw   xmm0, xmm1
4185     paddusw xmm0, xmm4
4186     psubusw xmm1, xmm5, xmm0
4187     packsswb xmm1, xmm1
4188     movq    [r6], xmm1
4189     ADS_END 2
4190
4191 cglobal pixel_ads1, 6,7,8
4192     movd    xmm7, [r0]
4193     movd    xmm6, r6m
4194     pshuflw xmm7, xmm7, 0
4195     pshuflw xmm6, xmm6, 0
4196     punpcklqdq xmm7, xmm7
4197     punpcklqdq xmm6, xmm6
4198     ADS_START
4199 .loop:
4200     movdqu  xmm0, [r1]
4201     movdqu  xmm1, [r1+16]
4202     psubw   xmm0, xmm7
4203     psubw   xmm1, xmm7
4204     movdqu  xmm2, [r3]
4205     movdqu  xmm3, [r3+16]
4206     ABSW    xmm0, xmm0, xmm4
4207     ABSW    xmm1, xmm1, xmm5
4208     paddusw xmm0, xmm2
4209     paddusw xmm1, xmm3
4210     psubusw xmm4, xmm6, xmm0
4211     psubusw xmm5, xmm6, xmm1
4212     packsswb xmm4, xmm5
4213     movdqa  [r6], xmm4
4214     ADS_END 4
4215 %endmacro
4216
4217 INIT_XMM sse2
4218 ADS_XMM
4219 INIT_XMM ssse3
4220 ADS_XMM
4221 INIT_XMM avx
4222 ADS_XMM
4223
4224 ; int pixel_ads_mvs( int16_t *mvs, uint8_t *masks, int width )
4225 ; {
4226 ;     int nmv=0, i, j;
4227 ;     *(uint32_t*)(masks+width) = 0;
4228 ;     for( i=0; i<width; i+=8 )
4229 ;     {
4230 ;         uint64_t mask = *(uint64_t*)(masks+i);
4231 ;         if( !mask ) continue;
4232 ;         for( j=0; j<8; j++ )
4233 ;             if( mask & (255<<j*8) )
4234 ;                 mvs[nmv++] = i+j;
4235 ;     }
4236 ;     return nmv;
4237 ; }
4238
4239 %macro TEST 1
4240     mov     [r4+r0*2], r1w
4241     test    r2d, 0xff<<(%1*8)
4242     setne   r3b
4243     add     r0d, r3d
4244     inc     r1d
4245 %endmacro
4246
4247 INIT_MMX
4248 cglobal pixel_ads_mvs, 0,7,0
4249 ads_mvs:
4250     lea     r6,  [r4+r5+15]
4251     and     r6,  ~15;
4252     ; mvs = r4
4253     ; masks = r6
4254     ; width = r5
4255     ; clear last block in case width isn't divisible by 8. (assume divisible by 4, so clearing 4 bytes is enough.)
4256     xor     r0d, r0d
4257     xor     r1d, r1d
4258     mov     [r6+r5], r0d
4259     jmp .loopi
4260 ALIGN 16
4261 .loopi0:
4262     add     r1d, 8
4263     cmp     r1d, r5d
4264     jge .end
4265 .loopi:
4266     mov     r2,  [r6+r1]
4267 %ifdef ARCH_X86_64
4268     test    r2,  r2
4269 %else
4270     mov     r3,  r2
4271     add    r3d, [r6+r1+4]
4272 %endif
4273     jz .loopi0
4274     xor     r3d, r3d
4275     TEST 0
4276     TEST 1
4277     TEST 2
4278     TEST 3
4279 %ifdef ARCH_X86_64
4280     shr     r2,  32
4281 %else
4282     mov     r2d, [r6+r1]
4283 %endif
4284     TEST 0
4285     TEST 1
4286     TEST 2
4287     TEST 3
4288     cmp     r1d, r5d
4289     jl .loopi
4290 .end:
4291     movifnidn eax, r0d
4292     RET