vp9lpf/x86: make filter_16_h work on 32-bit.
[ffmpeg.git] / libavcodec / x86 / vp9lpf.asm
1 ;******************************************************************************
2 ;* VP9 loop filter SIMD optimizations
3 ;*
4 ;* Copyright (C) 2013-2014 Clément Bœsch <u pkh me>
5 ;* Copyright (C) 2014 Ronald S. Bultje <rsbultje@gmail.com>
6 ;*
7 ;* This file is part of Libav.
8 ;*
9 ;* Libav is free software; you can redistribute it and/or
10 ;* modify it under the terms of the GNU Lesser General Public
11 ;* License as published by the Free Software Foundation; either
12 ;* version 2.1 of the License, or (at your option) any later version.
13 ;*
14 ;* Libav is distributed in the hope that it will be useful,
15 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 ;* Lesser General Public License for more details.
18 ;*
19 ;* You should have received a copy of the GNU Lesser General Public
20 ;* License along with Libav; if not, write to the Free Software
21 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 ;******************************************************************************
23
24
25 %include "libavutil/x86/x86util.asm"
26
27 SECTION_RODATA
28
29 cextern pb_3
30 cextern pb_80
31
32 pb_4:   times 16 db 0x04
33 pb_10:  times 16 db 0x10
34 pb_40:  times 16 db 0x40
35 pb_81:  times 16 db 0x81
36 pb_f8:  times 16 db 0xf8
37 pb_fe:  times 16 db 0xfe
38 pb_ff:  times 16 db 0xff
39
40 pw_4:   times  8 dw 4
41 pw_8:   times  8 dw 8
42
43 ; with mix functions, two 8-bit thresholds are stored in a 16-bit storage,
44 ; the following mask is used to splat both in the same register
45 mask_mix: times 8 db 0
46           times 8 db 1
47
48 mask_mix84: times 8 db 0xff
49             times 8 db 0x00
50 mask_mix48: times 8 db 0x00
51             times 8 db 0xff
52
53 SECTION .text
54
55 %macro SCRATCH 3
56 %if ARCH_X86_64
57     SWAP                %1, %2
58 %else
59     mova              [%3], m%1
60 %endif
61 %endmacro
62
63 %macro UNSCRATCH 3
64 %if ARCH_X86_64
65     SWAP                %1, %2
66 %else
67     mova               m%1, [%3]
68 %endif
69 %endmacro
70
71 ; %1 = abs(%2-%3)
72 %macro ABSSUB 4 ; dst, src1 (RO), src2 (RO), tmp
73 %if ARCH_X86_64
74     psubusb             %1, %3, %2
75     psubusb             %4, %2, %3
76 %else
77     mova                %1, %3
78     mova                %4, %2
79     psubusb             %1, %2
80     psubusb             %4, %3
81 %endif
82     por                 %1, %4
83 %endmacro
84
85 ; %1 = %1>%2
86 %macro CMP_GT 2-3 ; src/dst, cmp, pb_80
87 %if %0 == 3
88     pxor                %1, %3
89 %endif
90     pcmpgtb             %1, %2
91 %endmacro
92
93 ; %1 = abs(%2-%3) > %4
94 %macro ABSSUB_GT 5-6 [pb_80]; dst, src1, src2, cmp, tmp, [pb_80]
95     ABSSUB              %1, %2, %3, %5      ; dst = abs(src1-src2)
96     CMP_GT              %1, %4, %6          ; dst > cmp
97 %endmacro
98
99 %macro MASK_APPLY 4 ; %1=new_data/dst %2=old_data %3=mask %4=tmp
100     pand                %1, %3              ; new &= mask
101     pandn               %4, %3, %2          ; tmp = ~mask & old
102     por                 %1, %4              ; new&mask | old&~mask
103 %endmacro
104
105 %macro UNPACK 4
106 %if ARCH_X86_64
107     punpck%1bw          %2, %3, %4
108 %else
109     mova                %2, %3
110     punpck%1bw          %2, %4
111 %endif
112 %endmacro
113
114 %macro FILTER_SUBx2_ADDx2 11 ; %1=dst %2=h/l %3=cache %4=stack_off %5=sub1 %6=sub2 %7=add1
115                              ; %8=add2 %9=rshift, [unpack], [unpack_is_mem_on_x86_32]
116     psubw               %3, [rsp+%4+%5*32]
117     psubw               %3, [rsp+%4+%6*32]
118     paddw               %3, [rsp+%4+%7*32]
119 %ifnidn %10, ""
120 %if %11 == 0
121     punpck%2bw          %1, %10, m0
122 %else
123     UNPACK          %2, %1, %10, m0
124 %endif
125     mova    [rsp+%4+%8*32], %1
126     paddw               %3, %1
127 %else
128     paddw               %3, [rsp+%4+%8*32]
129 %endif
130     psraw               %1, %3, %9
131 %endmacro
132
133 ; FIXME interleave l/h better (for instruction pairing)
134 %macro FILTER_INIT 9 ; tmp1, tmp2, cacheL, cacheH, dstp, stack_off, filterid, mask, source
135     FILTER%7_INIT       %1, l, %3, %6 +  0
136     FILTER%7_INIT       %2, h, %4, %6 + 16
137     packuswb            %1, %2
138     MASK_APPLY          %1, %9, %8, %2
139     mova                %5, %1
140 %endmacro
141
142
143 %macro FILTER_UPDATE 12-16 "", "", "", 0 ; tmp1, tmp2, cacheL, cacheH, dstp, stack_off, -, -, +, +, rshift,
144                                          ; mask, [source], [unpack + src], [unpack_is_mem_on_x86_32]
145 ; FIXME interleave this properly with the subx2/addx2
146 %ifnidn %15, ""
147 %if %16 == 0 || ARCH_X86_64
148     mova               %14, %15
149 %endif
150 %endif
151     FILTER_SUBx2_ADDx2  %1, l, %3, %6 +  0, %7, %8, %9, %10, %11, %14, %16
152     FILTER_SUBx2_ADDx2  %2, h, %4, %6 + 16, %7, %8, %9, %10, %11, %14, %16
153     packuswb            %1, %2
154 %ifnidn %13, ""
155     MASK_APPLY          %1, %13, %12, %2
156 %else
157     MASK_APPLY          %1, %5, %12, %2
158 %endif
159     mova                %5, %1
160 %endmacro
161
162 %macro SRSHIFT3B_2X 4 ; reg1, reg2, [pb_10], tmp
163     mova                %4, [pb_f8]
164     pand                %1, %4
165     pand                %2, %4
166     psrlq               %1, 3
167     psrlq               %2, 3
168     pxor                %1, %3
169     pxor                %2, %3
170     psubb               %1, %3
171     psubb               %2, %3
172 %endmacro
173
174 %macro EXTRACT_POS_NEG 3 ; i8, neg, pos
175     pxor                %3, %3
176     pxor                %2, %2
177     pcmpgtb             %3, %1                          ; i8 < 0 mask
178     psubb               %2, %1                          ; neg values (only the originally - will be kept)
179     pand                %2, %3                          ; negative values of i8 (but stored as +)
180     pandn               %3, %1                          ; positive values of i8
181 %endmacro
182
183 ; clip_u8(u8 + i8)
184 %macro SIGN_ADD 4 ; dst, u8, i8, tmp1
185     EXTRACT_POS_NEG     %3, %4, %1
186     paddusb             %1, %2                          ; add the positives
187     psubusb             %1, %4                          ; sub the negatives
188 %endmacro
189
190 ; clip_u8(u8 - i8)
191 %macro SIGN_SUB 4 ; dst, u8, i8, tmp1
192     EXTRACT_POS_NEG     %3, %1, %4
193     paddusb             %1, %2                          ; add the negatives
194     psubusb             %1, %4                          ; sub the positives
195 %endmacro
196
197 %macro FILTER6_INIT 4 ; %1=dst %2=h/l %3=cache, %4=stack_off
198     UNPACK          %2, %1, rp3, m0                     ; p3: B->W
199     mova     [rsp+%4+0*32], %1
200     paddw               %3, %1, %1                      ; p3*2
201     paddw               %3, %1                          ; p3*3
202     punpck%2bw          %1, m1,  m0                     ; p2: B->W
203     mova     [rsp+%4+1*32], %1
204     paddw               %3, %1                          ; p3*3 + p2
205     paddw               %3, %1                          ; p3*3 + p2*2
206     UNPACK          %2, %1, rp1, m0                     ; p1: B->W
207     mova     [rsp+%4+2*32], %1
208     paddw               %3, %1                          ; p3*3 + p2*2 + p1
209     UNPACK          %2, %1, rp0, m0                     ; p0: B->W
210     mova     [rsp+%4+3*32], %1
211     paddw               %3, %1                          ; p3*3 + p2*2 + p1 + p0
212     UNPACK          %2, %1, rq0, m0                     ; q0: B->W
213     mova     [rsp+%4+4*32], %1
214     paddw               %3, %1                          ; p3*3 + p2*2 + p1 + p0 + q0
215     paddw               %3, [pw_4]                      ; p3*3 + p2*2 + p1 + p0 + q0 + 4
216     psraw               %1, %3, 3                       ; (p3*3 + p2*2 + p1 + p0 + q0 + 4) >> 3
217 %endmacro
218
219 %macro FILTER14_INIT 4 ; %1=dst %2=h/l %3=cache, %4=stack_off
220     punpck%2bw          %1, m2, m0                      ; p7: B->W
221     mova    [rsp+%4+ 8*32], %1
222     psllw               %3, %1, 3                       ; p7*8
223     psubw               %3, %1                          ; p7*7
224     punpck%2bw          %1, m3, m0                      ; p6: B->W
225     mova    [rsp+%4+ 9*32], %1
226     paddw               %3, %1                          ; p7*7 + p6
227     paddw               %3, %1                          ; p7*7 + p6*2
228     UNPACK          %2, %1, rp5, m0                     ; p5: B->W
229     mova    [rsp+%4+10*32], %1
230     paddw               %3, %1                          ; p7*7 + p6*2 + p5
231     UNPACK          %2, %1, rp4, m0                     ; p4: B->W
232     mova    [rsp+%4+11*32], %1
233     paddw               %3, %1                          ; p7*7 + p6*2 + p5 + p4
234     paddw               %3, [rsp+%4+ 0*32]              ; p7*7 + p6*2 + p5 + p4 + p3
235     paddw               %3, [rsp+%4+ 1*32]              ; p7*7 + p6*2 + p5 + .. + p2
236     paddw               %3, [rsp+%4+ 2*32]              ; p7*7 + p6*2 + p5 + .. + p1
237     paddw               %3, [rsp+%4+ 3*32]              ; p7*7 + p6*2 + p5 + .. + p0
238     paddw               %3, [rsp+%4+ 4*32]              ; p7*7 + p6*2 + p5 + .. + p0 + q0
239     paddw               %3, [pw_8]                      ; p7*7 + p6*2 + p5 + .. + p0 + q0 + 8
240     psraw               %1, %3, 4                       ; (p7*7 + p6*2 + p5 + .. + p0 + q0 + 8) >> 4
241 %endmacro
242
243 %macro TRANSPOSE16x16B 17
244     mova %17, m%16
245     SBUTTERFLY bw,  %1,  %2,  %16
246     SBUTTERFLY bw,  %3,  %4,  %16
247     SBUTTERFLY bw,  %5,  %6,  %16
248     SBUTTERFLY bw,  %7,  %8,  %16
249     SBUTTERFLY bw,  %9,  %10, %16
250     SBUTTERFLY bw,  %11, %12, %16
251     SBUTTERFLY bw,  %13, %14, %16
252     mova m%16,  %17
253     mova  %17, m%14
254     SBUTTERFLY bw,  %15, %16, %14
255     SBUTTERFLY wd,  %1,  %3,  %14
256     SBUTTERFLY wd,  %2,  %4,  %14
257     SBUTTERFLY wd,  %5,  %7,  %14
258     SBUTTERFLY wd,  %6,  %8,  %14
259     SBUTTERFLY wd,  %9,  %11, %14
260     SBUTTERFLY wd,  %10, %12, %14
261     SBUTTERFLY wd,  %13, %15, %14
262     mova m%14,  %17
263     mova  %17, m%12
264     SBUTTERFLY wd,  %14, %16, %12
265     SBUTTERFLY dq,  %1,  %5,  %12
266     SBUTTERFLY dq,  %2,  %6,  %12
267     SBUTTERFLY dq,  %3,  %7,  %12
268     SBUTTERFLY dq,  %4,  %8,  %12
269     SBUTTERFLY dq,  %9,  %13, %12
270     SBUTTERFLY dq,  %10, %14, %12
271     SBUTTERFLY dq,  %11, %15, %12
272     mova m%12, %17
273     mova  %17, m%8
274     SBUTTERFLY dq,  %12, %16, %8
275     SBUTTERFLY qdq, %1,  %9,  %8
276     SBUTTERFLY qdq, %2,  %10, %8
277     SBUTTERFLY qdq, %3,  %11, %8
278     SBUTTERFLY qdq, %4,  %12, %8
279     SBUTTERFLY qdq, %5,  %13, %8
280     SBUTTERFLY qdq, %6,  %14, %8
281     SBUTTERFLY qdq, %7,  %15, %8
282     mova m%8, %17
283     mova %17, m%1
284     SBUTTERFLY qdq, %8,  %16, %1
285     mova m%1, %17
286     SWAP %2,  %9
287     SWAP %3,  %5
288     SWAP %4,  %13
289     SWAP %6,  %11
290     SWAP %8,  %15
291     SWAP %12, %14
292 %endmacro
293
294 %macro TRANSPOSE8x8B 13
295     SBUTTERFLY bw,  %1, %2, %7
296     movdq%10 m%7, %9
297     movdqa %11, m%2
298     SBUTTERFLY bw,  %3, %4, %2
299     SBUTTERFLY bw,  %5, %6, %2
300     SBUTTERFLY bw,  %7, %8, %2
301     SBUTTERFLY wd,  %1, %3, %2
302     movdqa m%2, %11
303     movdqa %11, m%3
304     SBUTTERFLY wd,  %2, %4, %3
305     SBUTTERFLY wd,  %5, %7, %3
306     SBUTTERFLY wd,  %6, %8, %3
307     SBUTTERFLY dq, %1, %5, %3
308     SBUTTERFLY dq, %2, %6, %3
309     movdqa m%3, %11
310     movh   %12, m%2
311     movhps %13, m%2
312     SBUTTERFLY dq, %3, %7, %2
313     SBUTTERFLY dq, %4, %8, %2
314     SWAP %2, %5
315     SWAP %4, %7
316 %endmacro
317
318 %macro DEFINE_REAL_P7_TO_Q7 0-1 0
319 %define P7 dstq  + 4*mstrideq  + %1
320 %define P6 dstq  +   mstride3q + %1
321 %define P5 dstq  + 2*mstrideq  + %1
322 %define P4 dstq  +   mstrideq  + %1
323 %define P3 dstq                + %1
324 %define P2 dstq  +    strideq  + %1
325 %define P1 dstq  + 2* strideq  + %1
326 %define P0 dstq  +    stride3q + %1
327 %define Q0 dstq  + 4* strideq  + %1
328 %define Q1 dst2q +   mstride3q + %1
329 %define Q2 dst2q + 2*mstrideq  + %1
330 %define Q3 dst2q +   mstrideq  + %1
331 %define Q4 dst2q               + %1
332 %define Q5 dst2q +    strideq  + %1
333 %define Q6 dst2q + 2* strideq  + %1
334 %define Q7 dst2q +    stride3q + %1
335 %endmacro
336
337 %macro DEFINE_TRANSPOSED_P7_TO_Q7 0-1 0
338 %define P3 rsp +   0 + %1
339 %define P2 rsp +  16 + %1
340 %define P1 rsp +  32 + %1
341 %define P0 rsp +  48 + %1
342 %define Q0 rsp +  64 + %1
343 %define Q1 rsp +  80 + %1
344 %define Q2 rsp +  96 + %1
345 %define Q3 rsp + 112 + %1
346 %define P7 rsp + 128 + %1
347 %define P6 rsp + 144 + %1
348 %define P5 rsp + 160 + %1
349 %define P4 rsp + 176 + %1
350 %define Q4 rsp + 192 + %1
351 %define Q5 rsp + 208 + %1
352 %define Q6 rsp + 224 + %1
353 %define Q7 rsp + 240 + %1
354 %endmacro
355
356 ; ..............AB -> AAAAAAAABBBBBBBB
357 %macro SPLATB_MIX 1-2 [mask_mix]
358 %if cpuflag(ssse3)
359     pshufb     %1, %2
360 %else
361     punpcklbw  %1, %1
362     punpcklwd  %1, %1
363     punpckldq  %1, %1
364 %endif
365 %endmacro
366
367 %macro LOOPFILTER 5 ; %1=v/h %2=size1 %3+%4=stack, %5=32bit stack only
368 %if UNIX64
369 cglobal vp9_loop_filter_%1_%2_16, 5, 9, 16, %3 + %4, dst, stride, E, I, H, mstride, dst2, stride3, mstride3
370 %else
371 %if WIN64
372 cglobal vp9_loop_filter_%1_%2_16, 4, 8, 16, %3 + %4, dst, stride, E, I, mstride, dst2, stride3, mstride3
373 %else
374 cglobal vp9_loop_filter_%1_%2_16, 2, 6, 16, %3 + %4 + %5, dst, stride, mstride, dst2, stride3, mstride3
375 %define Ed dword r2m
376 %define Id dword r3m
377 %endif
378 %define Hd dword r4m
379 %endif
380
381     mov               mstrideq, strideq
382     neg               mstrideq
383
384     lea               stride3q, [strideq*3]
385     lea              mstride3q, [mstrideq*3]
386
387 %ifidn %1, h
388 %if %2 > 16
389 %define movx movh
390     lea                   dstq, [dstq + 4*strideq - 4]
391 %else
392 %define movx movu
393     lea                   dstq, [dstq + 4*strideq - 8] ; go from top center (h pos) to center left (v pos)
394 %endif
395     lea                  dst2q, [dstq + 8*strideq]
396 %else
397     lea                   dstq, [dstq + 4*mstrideq]
398     lea                  dst2q, [dstq + 8*strideq]
399 %endif
400
401     DEFINE_REAL_P7_TO_Q7
402
403 %ifidn %1, h
404     movx                    m0, [P7]
405     movx                    m1, [P6]
406     movx                    m2, [P5]
407     movx                    m3, [P4]
408     movx                    m4, [P3]
409     movx                    m5, [P2]
410 %if ARCH_X86_64 || %2 != 16
411     movx                    m6, [P1]
412 %endif
413     movx                    m7, [P0]
414 %if ARCH_X86_64
415     movx                    m8, [Q0]
416     movx                    m9, [Q1]
417     movx                   m10, [Q2]
418     movx                   m11, [Q3]
419     movx                   m12, [Q4]
420     movx                   m13, [Q5]
421     movx                   m14, [Q6]
422     movx                   m15, [Q7]
423     DEFINE_TRANSPOSED_P7_TO_Q7
424 %if %2 == 16
425     TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp]
426     mova           [P7],  m0
427     mova           [P6],  m1
428     mova           [P5],  m2
429     mova           [P4],  m3
430 %else ; %2 == 44/48/84/88
431     ; 8x16 transpose
432     punpcklbw        m0,  m1
433     punpcklbw        m2,  m3
434     punpcklbw        m4,  m5
435     punpcklbw        m6,  m7
436     punpcklbw        m8,  m9
437     punpcklbw       m10, m11
438     punpcklbw       m12, m13
439     punpcklbw       m14, m15
440     TRANSPOSE8x8W     0, 2, 4, 6, 8, 10, 12, 14, 15
441     SWAP              0,  4
442     SWAP              2,  5
443     SWAP              0,  6
444     SWAP              0,  7
445     SWAP             10,  9
446     SWAP             12, 10
447     SWAP             14, 11
448 %endif ; %2
449     mova           [P3],  m4
450     mova           [P2],  m5
451     mova           [P1],  m6
452     mova           [P0],  m7
453     mova           [Q0],  m8
454     mova           [Q1],  m9
455     mova           [Q2], m10
456     mova           [Q3], m11
457 %if %2 == 16
458     mova           [Q4], m12
459     mova           [Q5], m13
460     mova           [Q6], m14
461     mova           [Q7], m15
462 %endif ; %2
463 %else ; x86-32
464 %if %2 == 16
465     TRANSPOSE8x8B    0, 1, 2, 3, 4, 5, 6, 7, [P1], u, [rsp+%3+%4], [rsp+64], [rsp+80]
466     DEFINE_TRANSPOSED_P7_TO_Q7
467     movh          [P7], m0
468     movh          [P5], m1
469     movh          [P3], m2
470     movh          [P1], m3
471     movh          [Q2], m5
472     movh          [Q4], m6
473     movh          [Q6], m7
474     movhps        [P6], m0
475     movhps        [P4], m1
476     movhps        [P2], m2
477     movhps        [P0], m3
478     movhps        [Q3], m5
479     movhps        [Q5], m6
480     movhps        [Q7], m7
481     DEFINE_REAL_P7_TO_Q7
482     movx                    m0, [Q0]
483     movx                    m1, [Q1]
484     movx                    m2, [Q2]
485     movx                    m3, [Q3]
486     movx                    m4, [Q4]
487     movx                    m5, [Q5]
488     movx                    m7, [Q7]
489     TRANSPOSE8x8B 0, 1, 2, 3, 4, 5, 6, 7, [Q6], u, [rsp+%3+%4], [rsp+72], [rsp+88]
490     DEFINE_TRANSPOSED_P7_TO_Q7 8
491     movh          [P7], m0
492     movh          [P5], m1
493     movh          [P3], m2
494     movh          [P1], m3
495     movh          [Q2], m5
496     movh          [Q4], m6
497     movh          [Q6], m7
498     movhps        [P6], m0
499     movhps        [P4], m1
500     movhps        [P2], m2
501     movhps        [P0], m3
502     movhps        [Q3], m5
503     movhps        [Q5], m6
504     movhps        [Q7], m7
505     DEFINE_TRANSPOSED_P7_TO_Q7
506 %else ; %2 == 44/48/84/88
507     punpcklbw        m0, m1
508     punpcklbw        m2, m3
509     punpcklbw        m4, m5
510     punpcklbw        m6, m7
511     movx             m1, [Q0]
512     movx             m3, [Q1]
513     movx             m5, [Q2]
514     movx             m7, [Q3]
515     punpcklbw        m1, m3
516     punpcklbw        m5, m7
517     movx             m3, [Q4]
518     movx             m7, [Q5]
519     punpcklbw        m3, m7
520     mova          [rsp], m3
521     movx             m3, [Q6]
522     movx             m7, [Q7]
523     punpcklbw        m3, m7
524     DEFINE_TRANSPOSED_P7_TO_Q7
525     TRANSPOSE8x8W     0, 2, 4, 6, 1, 5, 7, 3, [rsp], [Q0], 1
526     mova           [P3],  m0
527     mova           [P2],  m2
528     mova           [P1],  m4
529     mova           [P0],  m6
530     mova           [Q1],  m5
531     mova           [Q2],  m7
532     mova           [Q3],  m3
533 %endif ; %2
534 %endif ; x86-32/64
535 %endif ; %1 == h
536
537     ; calc fm mask
538 %if %2 == 16
539 %if cpuflag(ssse3)
540     pxor                m0, m0
541 %endif
542     SPLATB_REG          m2, I, m0                       ; I I I I ...
543     SPLATB_REG          m3, E, m0                       ; E E E E ...
544 %else
545 %if cpuflag(ssse3)
546     mova                m0, [mask_mix]
547 %endif
548     movd                m2, Id
549     movd                m3, Ed
550     SPLATB_MIX          m2, m0
551     SPLATB_MIX          m3, m0
552 %endif
553     mova                m0, [pb_80]
554     pxor                m2, m0
555     pxor                m3, m0
556 %if ARCH_X86_64
557 %ifidn %1, v
558     mova                m8, [P3]
559     mova                m9, [P2]
560     mova               m10, [P1]
561     mova               m11, [P0]
562     mova               m12, [Q0]
563     mova               m13, [Q1]
564     mova               m14, [Q2]
565     mova               m15, [Q3]
566 %else
567     ; In case of horizontal, P3..Q3 are already present in some registers due
568     ; to the previous transpose, so we just swap registers.
569     SWAP                 8,  4, 12
570     SWAP                 9,  5, 13
571     SWAP                10,  6, 14
572     SWAP                11,  7, 15
573 %endif
574 %define rp3 m8
575 %define rp2 m9
576 %define rp1 m10
577 %define rp0 m11
578 %define rq0 m12
579 %define rq1 m13
580 %define rq2 m14
581 %define rq3 m15
582 %else
583 %define rp3 [P3]
584 %define rp2 [P2]
585 %define rp1 [P1]
586 %define rp0 [P0]
587 %define rq0 [Q0]
588 %define rq1 [Q1]
589 %define rq2 [Q2]
590 %define rq3 [Q3]
591 %endif
592     ABSSUB_GT           m5, rp3, rp2, m2, m7, m0        ; m5 = abs(p3-p2) <= I
593     ABSSUB_GT           m1, rp2, rp1, m2, m7, m0        ; m1 = abs(p2-p1) <= I
594     por                 m5, m1
595     ABSSUB_GT           m1, rp1, rp0, m2, m7, m0        ; m1 = abs(p1-p0) <= I
596     por                 m5, m1
597     ABSSUB_GT           m1, rq0, rq1, m2, m7, m0        ; m1 = abs(q1-q0) <= I
598     por                 m5, m1
599     ABSSUB_GT           m1, rq1, rq2, m2, m7, m0        ; m1 = abs(q2-q1) <= I
600     por                 m5, m1
601     ABSSUB_GT           m1, rq2, rq3, m2, m7, m0        ; m1 = abs(q3-q2) <= I
602     por                 m5, m1
603     ABSSUB              m1, rp0, rq0, m7                ; abs(p0-q0)
604     paddusb             m1, m1                          ; abs(p0-q0) * 2
605     ABSSUB              m2, rp1, rq1, m7                ; abs(p1-q1)
606     pand                m2, [pb_fe]                     ; drop lsb so shift can work
607     psrlq               m2, 1                           ; abs(p1-q1)/2
608     paddusb             m1, m2                          ; abs(p0-q0)*2 + abs(p1-q1)/2
609     pxor                m1, m0
610     pcmpgtb             m1, m3
611     por                 m1, m5                          ; fm final value
612     SWAP                 1, 3
613     pxor                m3, [pb_ff]
614
615     ; (m3: fm, m8..15: p3 p2 p1 p0 q0 q1 q2 q3)
616     ; calc flat8in (if not 44_16) and hev masks
617 %if %2 != 44
618     mova                m6, [pb_81]                     ; [1 1 1 1 ...] ^ 0x80
619     ABSSUB_GT           m2, rp3, rp0, m6, m5            ; abs(p3 - p0) <= 1
620 %if ARCH_X86_64
621     mova                m8, [pb_80]
622 %define rb80 m8
623 %else
624 %define rb80 [pb_80]
625 %endif
626     ABSSUB_GT           m1, rp2, rp0, m6, m5, rb80      ; abs(p2 - p0) <= 1
627     por                 m2, m1
628     ABSSUB              m4, rp1, rp0, m5                ; abs(p1 - p0)
629 %if %2 == 16
630 %if cpuflag(ssse3)
631     pxor                m0, m0
632 %endif
633     SPLATB_REG          m7, H, m0                       ; H H H H ...
634 %else
635     movd                m7, Hd
636     SPLATB_MIX          m7
637 %endif
638     pxor                m7, rb80
639     pxor                m4, rb80
640     pcmpgtb             m0, m4, m7                      ; abs(p1 - p0) > H (1/2 hev condition)
641     CMP_GT              m4, m6                          ; abs(p1 - p0) <= 1
642     por                 m2, m4                          ; (flat8in)
643     ABSSUB              m4, rq1, rq0, m1                ; abs(q1 - q0)
644     pxor                m4, rb80
645     pcmpgtb             m5, m4, m7                      ; abs(q1 - q0) > H (2/2 hev condition)
646     por                 m0, m5                          ; hev final value
647     CMP_GT              m4, m6                          ; abs(q1 - q0) <= 1
648     por                 m2, m4                          ; (flat8in)
649     ABSSUB_GT           m1, rq2, rq0, m6, m5, rb80      ; abs(q2 - q0) <= 1
650     por                 m2, m1
651     ABSSUB_GT           m1, rq3, rq0, m6, m5, rb80      ; abs(q3 - q0) <= 1
652     por                 m2, m1                          ; flat8in final value
653     pxor                m2, [pb_ff]
654 %if %2 == 84 || %2 == 48
655     pand                m2, [mask_mix%2]
656 %endif
657 %else
658     mova                m6, [pb_80]
659     movd                m7, Hd
660     SPLATB_MIX          m7
661     pxor                m7, m6
662     ABSSUB              m4, rp1, rp0, m1                ; abs(p1 - p0)
663     pxor                m4, m6
664     pcmpgtb             m0, m4, m7                      ; abs(p1 - p0) > H (1/2 hev condition)
665     ABSSUB              m4, rq1, rq0, m1                ; abs(q1 - q0)
666     pxor                m4, m6
667     pcmpgtb             m5, m4, m7                      ; abs(q1 - q0) > H (2/2 hev condition)
668     por                 m0, m5                          ; hev final value
669 %endif
670
671 %if %2 == 16
672     ; (m0: hev, m2: flat8in, m3: fm, m6: pb_81, m9..15: p2 p1 p0 q0 q1 q2 q3)
673     ; calc flat8out mask
674 %if ARCH_X86_64
675     mova                m8, [P7]
676     mova                m9, [P6]
677 %define rp7 m8
678 %define rp6 m9
679 %else
680 %define rp7 [P7]
681 %define rp6 [P6]
682 %endif
683     ABSSUB_GT           m1, rp7, rp0, m6, m5            ; abs(p7 - p0) <= 1
684     ABSSUB_GT           m7, rp6, rp0, m6, m5            ; abs(p6 - p0) <= 1
685     por                 m1, m7
686 %if ARCH_X86_64
687     mova                m8, [P5]
688     mova                m9, [P4]
689 %define rp5 m8
690 %define rp4 m9
691 %else
692 %define rp5 [P5]
693 %define rp4 [P4]
694 %endif
695     ABSSUB_GT           m7, rp5, rp0, m6, m5            ; abs(p5 - p0) <= 1
696     por                 m1, m7
697     ABSSUB_GT           m7, rp4, rp0, m6, m5            ; abs(p4 - p0) <= 1
698     por                 m1, m7
699 %if ARCH_X86_64
700     mova                m14, [Q4]
701     mova                m15, [Q5]
702 %define rq4 m14
703 %define rq5 m15
704 %else
705 %define rq4 [Q4]
706 %define rq5 [Q5]
707 %endif
708     ABSSUB_GT           m7, rq4, rq0, m6, m5            ; abs(q4 - q0) <= 1
709     por                 m1, m7
710     ABSSUB_GT           m7, rq5, rq0, m6, m5            ; abs(q5 - q0) <= 1
711     por                 m1, m7
712 %if ARCH_X86_64
713     mova                m14, [Q6]
714     mova                m15, [Q7]
715 %define rq6 m14
716 %define rq7 m15
717 %else
718 %define rq6 [Q6]
719 %define rq7 [Q7]
720 %endif
721     ABSSUB_GT           m7, rq6, rq0, m6, m5            ; abs(q4 - q0) <= 1
722     por                 m1, m7
723     ABSSUB_GT           m7, rq7, rq0, m6, m5            ; abs(q5 - q0) <= 1
724     por                 m1, m7                          ; flat8out final value
725     pxor                m1, [pb_ff]
726 %endif
727
728     ; if (fm) {
729     ;     if (out && in) filter_14()
730     ;     else if (in)   filter_6()
731     ;     else if (hev)  filter_2()
732     ;     else           filter_4()
733     ; }
734     ;
735     ; f14:                                                                            fm &  out &  in
736     ; f6:  fm & ~f14 & in        => fm & ~(out & in) & in                          => fm & ~out &  in
737     ; f2:  fm & ~f14 & ~f6 & hev => fm & ~(out & in) & ~(~out & in) & hev          => fm &  ~in &  hev
738     ; f4:  fm & ~f14 & ~f6 & ~f2 => fm & ~(out & in) & ~(~out & in) & ~(~in & hev) => fm &  ~in & ~hev
739
740     ; (m0: hev, [m1: flat8out], [m2: flat8in], m3: fm, m8..15: p5 p4 p1 p0 q0 q1 q6 q7)
741     ; filter2()
742 %if %2 != 44
743     mova                m6, [pb_80]                     ; already in m6 if 44_16
744     SCRATCH              2, 15, rsp+%3+%4
745 %if %2 == 16
746     SCRATCH              1,  8, rsp+%3+%4+16
747 %endif
748 %endif
749     pxor                m2, m6, rq0                     ; q0 ^ 0x80
750     pxor                m4, m6, rp0                     ; p0 ^ 0x80
751     psubsb              m2, m4                          ; (signed) q0 - p0
752     pxor                m4, m6, rp1                     ; p1 ^ 0x80
753     pxor                m5, m6, rq1                     ; q1 ^ 0x80
754     psubsb              m4, m5                          ; (signed) p1 - q1
755     paddsb              m4, m2                          ;   (q0 - p0) + (p1 - q1)
756     paddsb              m4, m2                          ; 2*(q0 - p0) + (p1 - q1)
757     paddsb              m4, m2                          ; 3*(q0 - p0) + (p1 - q1)
758     paddsb              m6, m4, [pb_4]                  ; m6: f1 = clip(f + 4, 127)
759     paddsb              m4, [pb_3]                      ; m4: f2 = clip(f + 3, 127)
760 %if ARCH_X86_64
761     mova                m14, [pb_10]                    ; will be reused in filter4()
762 %define rb10 m14
763 %else
764 %define rb10 [pb_10]
765 %endif
766     SRSHIFT3B_2X        m6, m4, rb10, m7                ; f1 and f2 sign byte shift by 3
767     SIGN_SUB            m7, rq0, m6, m5                 ; m7 = q0 - f1
768     SIGN_ADD            m1, rp0, m4, m5                 ; m1 = p0 + f2
769 %if %2 != 44
770 %if ARCH_X86_64
771     pandn               m6, m15, m3                     ;  ~mask(in) & mask(fm)
772 %else
773     mova                m6, [rsp+%3+%4]
774     pandn               m6, m3
775 %endif
776     pand                m6, m0                          ; (~mask(in) & mask(fm)) & mask(hev)
777 %else
778     pand                m6, m3, m0
779 %endif
780     MASK_APPLY          m7, rq0, m6, m5                 ; m7 = filter2(q0) & mask / we write it in filter4()
781     MASK_APPLY          m1, rp0, m6, m5                 ; m1 = filter2(p0) & mask / we write it in filter4()
782
783     ; (m0: hev, m1: p0', m2: q0-p0, m3: fm, m7: q0', [m8: flat8out], m10..13: p1 p0 q0 q1, m14: pb_10, [m15: flat8in], )
784     ; filter4()
785     mova                m4, m2
786     paddsb              m2, m4                          ; 2 * (q0 - p0)
787     paddsb              m2, m4                          ; 3 * (q0 - p0)
788     paddsb              m6, m2, [pb_4]                  ; m6:  f1 = clip(f + 4, 127)
789     paddsb              m2, [pb_3]                      ; m2: f2 = clip(f + 3, 127)
790     SRSHIFT3B_2X        m6, m2, rb10, m4                ; f1 and f2 sign byte shift by 3
791 %if %2 != 44
792 %if ARCH_X86_64
793     pandn               m5, m15, m3                     ;               ~mask(in) & mask(fm)
794 %else
795     mova                m5, [rsp+%3+%4]
796     pandn               m5, m3
797 %endif
798     pandn               m0, m5                          ; ~mask(hev) & (~mask(in) & mask(fm))
799 %else
800     pandn               m0, m3
801 %endif
802     SIGN_SUB            m5, rq0, m6, m4                 ; q0 - f1
803     MASK_APPLY          m5, m7, m0, m4                  ; filter4(q0) & mask
804     mova                [Q0], m5
805     SIGN_ADD            m7, rp0, m2, m4                 ; p0 + f2
806     MASK_APPLY          m7, m1, m0, m4                  ; filter4(p0) & mask
807     mova                [P0], m7
808     paddb               m6, [pb_80]                     ;
809     pxor                m1, m1                          ;   f=(f1+1)>>1
810     pavgb               m6, m1                          ;
811     psubb               m6, [pb_40]                     ;
812     SIGN_ADD            m1, rp1, m6, m2                 ; p1 + f
813     SIGN_SUB            m4, rq1, m6, m2                 ; q1 - f
814     MASK_APPLY          m1, rp1, m0, m2                 ; m1 = filter4(p1)
815     MASK_APPLY          m4, rq1, m0, m2                 ; m4 = filter4(q1)
816     mova                [P1], m1
817     mova                [Q1], m4
818
819 %if %2 != 44
820     UNSCRATCH            2, 15, rsp+%3+%4
821 %endif
822
823     ; ([m1: flat8out], m2: flat8in, m3: fm, m10..13: p1 p0 q0 q1)
824     ; filter6()
825 %if %2 != 44
826     pxor                m0, m0
827 %if %2 > 16
828     pand                m3, m2
829 %else
830     pand                m2, m3                          ;               mask(fm) & mask(in)
831 %if ARCH_X86_64
832     pandn               m3, m8, m2                      ; ~mask(out) & (mask(fm) & mask(in))
833 %else
834     mova                m3, [rsp+%3+%4+16]
835     pandn               m3, m2
836 %endif
837 %endif
838 %if ARCH_X86_64
839     mova               m14, [P3]
840     mova                m9, [Q3]
841 %define rp3 m14
842 %define rq3 m9
843 %else
844 %define rp3 [P3]
845 %define rq3 [Q3]
846 %endif
847     mova                m1, [P2]
848     FILTER_INIT         m4, m5, m6, m7, [P2], %4, 6,             m3,  m1             ; [p2]
849     mova                m1, [Q2]
850     FILTER_UPDATE       m4, m5, m6, m7, [P1], %4, 0, 1, 2, 5, 3, m3,  "", rq1, "", 1 ; [p1] -p3 -p2 +p1 +q1
851     FILTER_UPDATE       m4, m5, m6, m7, [P0], %4, 0, 2, 3, 6, 3, m3,  "", m1         ; [p0] -p3 -p1 +p0 +q2
852     FILTER_UPDATE       m4, m5, m6, m7, [Q0], %4, 0, 3, 4, 7, 3, m3,  "", rq3, "", 1 ; [q0] -p3 -p0 +q0 +q3
853     FILTER_UPDATE       m4, m5, m6, m7, [Q1], %4, 1, 4, 5, 7, 3, m3,  ""             ; [q1] -p2 -q0 +q1 +q3
854     FILTER_UPDATE       m4, m5, m6, m7, [Q2], %4, 2, 5, 6, 7, 3, m3,  m1             ; [q2] -p1 -q1 +q2 +q3
855 %endif
856
857 %if %2 == 16
858     UNSCRATCH            1,  8, rsp+%3+%4+16
859 %endif
860
861     ; (m0: 0, [m1: flat8out], m2: fm & flat8in, m8..15: q2 q3 p1 p0 q0 q1 p3 p2)
862     ; filter14()
863     ;
864     ;                            m2  m3  m8  m9 m14 m15 m10 m11 m12 m13
865     ;
866     ;                                    q2  q3  p3  p2  p1  p0  q0  q1
867     ; p6  -7                     p7  p6  p5  p4   .   .   .   .   .
868     ; p5  -6  -p7 -p6 +p5 +q1     .   .   .                           .
869     ; p4  -5  -p7 -p5 +p4 +q2     .       .   .                      q2
870     ; p3  -4  -p7 -p4 +p3 +q3     .           .   .                  q3
871     ; p2  -3  -p7 -p3 +p2 +q4     .               .   .              q4
872     ; p1  -2  -p7 -p2 +p1 +q5     .                   .   .          q5
873     ; p0  -1  -p7 -p1 +p0 +q6     .                       .   .      q6
874     ; q0  +0  -p7 -p0 +q0 +q7     .                           .   .  q7
875     ; q1  +1  -p6 -q0 +q1 +q7    q1   .                           .   .
876     ; q2  +2  -p5 -q1 +q2 +q7     .  q2   .                           .
877     ; q3  +3  -p4 -q2 +q3 +q7         .  q3   .                       .
878     ; q4  +4  -p3 -q3 +q4 +q7             .  q4   .                   .
879     ; q5  +5  -p2 -q4 +q5 +q7                 .  q5   .               .
880     ; q6  +6  -p1 -q5 +q6 +q7                     .  q6   .           .
881
882 %if %2 == 16
883     pand            m1, m2                                                              ; mask(out) & (mask(fm) & mask(in))
884     mova            m2, [P7]
885     mova            m3, [P6]
886 %if ARCH_X86_64
887     mova            m8, [P5]
888     mova            m9, [P4]
889 %define rp5 m8
890 %define rp4 m9
891 %define rp5s m8
892 %define rp4s m9
893 %define rp3s m14
894 %define rq4 m8
895 %define rq5 m9
896 %define rq6 m14
897 %define rq7 m15
898 %define rq4s m8
899 %define rq5s m9
900 %define rq6s m14
901 %else
902 %define rp5 [P5]
903 %define rp4 [P4]
904 %define rp5s ""
905 %define rp4s ""
906 %define rp3s ""
907 %define rq4 [Q4]
908 %define rq5 [Q5]
909 %define rq6 [Q6]
910 %define rq7 [Q7]
911 %define rq4s ""
912 %define rq5s ""
913 %define rq6s ""
914 %endif
915     FILTER_INIT     m4, m5, m6, m7, [P6], %4, 14,                m1,  m3            ; [p6]
916     FILTER_UPDATE   m4, m5, m6, m7, [P5], %4,  8,  9, 10,  5, 4, m1, rp5s           ; [p5] -p7 -p6 +p5 +q1
917     FILTER_UPDATE   m4, m5, m6, m7, [P4], %4,  8, 10, 11,  6, 4, m1, rp4s           ; [p4] -p7 -p5 +p4 +q2
918     FILTER_UPDATE   m4, m5, m6, m7, [P3], %4,  8, 11,  0,  7, 4, m1, rp3s           ; [p3] -p7 -p4 +p3 +q3
919     FILTER_UPDATE   m4, m5, m6, m7, [P2], %4,  8,  0,  1, 12, 4, m1,  "", rq4, [Q4], 1 ; [p2] -p7 -p3 +p2 +q4
920     FILTER_UPDATE   m4, m5, m6, m7, [P1], %4,  8,  1,  2, 13, 4, m1,  "", rq5, [Q5], 1 ; [p1] -p7 -p2 +p1 +q5
921     FILTER_UPDATE   m4, m5, m6, m7, [P0], %4,  8,  2,  3, 14, 4, m1,  "", rq6, [Q6], 1 ; [p0] -p7 -p1 +p0 +q6
922     FILTER_UPDATE   m4, m5, m6, m7, [Q0], %4,  8,  3,  4, 15, 4, m1,  "", rq7, [Q7], 1 ; [q0] -p7 -p0 +q0 +q7
923     FILTER_UPDATE   m4, m5, m6, m7, [Q1], %4,  9,  4,  5, 15, 4, m1,  ""            ; [q1] -p6 -q0 +q1 +q7
924     FILTER_UPDATE   m4, m5, m6, m7, [Q2], %4, 10,  5,  6, 15, 4, m1,  ""            ; [q2] -p5 -q1 +q2 +q7
925     FILTER_UPDATE   m4, m5, m6, m7, [Q3], %4, 11,  6,  7, 15, 4, m1,  ""            ; [q3] -p4 -q2 +q3 +q7
926     FILTER_UPDATE   m4, m5, m6, m7, [Q4], %4,  0,  7, 12, 15, 4, m1, rq4s           ; [q4] -p3 -q3 +q4 +q7
927     FILTER_UPDATE   m4, m5, m6, m7, [Q5], %4,  1, 12, 13, 15, 4, m1, rq5s           ; [q5] -p2 -q4 +q5 +q7
928     FILTER_UPDATE   m4, m5, m6, m7, [Q6], %4,  2, 13, 14, 15, 4, m1, rq6s           ; [q6] -p1 -q5 +q6 +q7
929 %endif
930
931 %ifidn %1, h
932 %if %2 == 16
933     mova                    m0, [P7]
934     mova                    m1, [P6]
935     mova                    m2, [P5]
936     mova                    m3, [P4]
937     mova                    m4, [P3]
938     mova                    m5, [P2]
939 %if ARCH_X86_64
940     mova                    m6, [P1]
941 %endif
942     mova                    m7, [P0]
943 %if ARCH_X86_64
944     mova                    m8, [Q0]
945     mova                    m9, [Q1]
946     mova                   m10, [Q2]
947     mova                   m11, [Q3]
948     mova                   m12, [Q4]
949     mova                   m13, [Q5]
950     mova                   m14, [Q6]
951     mova                   m15, [Q7]
952     TRANSPOSE16x16B 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, [rsp]
953     DEFINE_REAL_P7_TO_Q7
954     movu  [P7],  m0
955     movu  [P6],  m1
956     movu  [P5],  m2
957     movu  [P4],  m3
958     movu  [P3],  m4
959     movu  [P2],  m5
960     movu  [P1],  m6
961     movu  [P0],  m7
962     movu  [Q0],  m8
963     movu  [Q1],  m9
964     movu  [Q2], m10
965     movu  [Q3], m11
966     movu  [Q4], m12
967     movu  [Q5], m13
968     movu  [Q6], m14
969     movu  [Q7], m15
970 %else
971     DEFINE_REAL_P7_TO_Q7
972     TRANSPOSE8x8B 0, 1, 2, 3, 4, 5, 6, 7, [rsp+32], a, [rsp+%3+%4], [Q0], [Q1]
973     movh   [P7],  m0
974     movh   [P5],  m1
975     movh   [P3],  m2
976     movh   [P1],  m3
977     movh   [Q2],  m5
978     movh   [Q4],  m6
979     movh   [Q6],  m7
980     movhps [P6],  m0
981     movhps [P4],  m1
982     movhps [P2],  m2
983     movhps [P0],  m3
984     movhps [Q3],  m5
985     movhps [Q5],  m6
986     movhps [Q7],  m7
987     DEFINE_TRANSPOSED_P7_TO_Q7
988     mova                    m0, [Q0]
989     mova                    m1, [Q1]
990     mova                    m2, [Q2]
991     mova                    m3, [Q3]
992     mova                    m4, [Q4]
993     mova                    m5, [Q5]
994     mova                    m7, [Q7]
995     DEFINE_REAL_P7_TO_Q7 8
996     TRANSPOSE8x8B 0, 1, 2, 3, 4, 5, 6, 7, [rsp+224], a, [rsp+%3+%4], [Q0], [Q1]
997     movh   [P7],  m0
998     movh   [P5],  m1
999     movh   [P3],  m2
1000     movh   [P1],  m3
1001     movh   [Q2],  m5
1002     movh   [Q4],  m6
1003     movh   [Q6],  m7
1004     movhps [P6],  m0
1005     movhps [P4],  m1
1006     movhps [P2],  m2
1007     movhps [P0],  m3
1008     movhps [Q3],  m5
1009     movhps [Q5],  m6
1010     movhps [Q7],  m7
1011 %endif
1012 %elif %2 == 44
1013     SWAP 0, 1   ; m0 = p1
1014     SWAP 1, 7   ; m1 = p0
1015     SWAP 2, 5   ; m2 = q0
1016     SWAP 3, 4   ; m3 = q1
1017     DEFINE_REAL_P7_TO_Q7 2
1018     SBUTTERFLY  bw, 0, 1, 4
1019     SBUTTERFLY  bw, 2, 3, 4
1020     SBUTTERFLY  wd, 0, 2, 4
1021     SBUTTERFLY  wd, 1, 3, 4
1022     movd  [P7], m0
1023     movd  [P3], m2
1024     movd  [Q0], m1
1025     movd  [Q4], m3
1026     psrldq  m0, 4
1027     psrldq  m1, 4
1028     psrldq  m2, 4
1029     psrldq  m3, 4
1030     movd  [P6], m0
1031     movd  [P2], m2
1032     movd  [Q1], m1
1033     movd  [Q5], m3
1034     psrldq  m0, 4
1035     psrldq  m1, 4
1036     psrldq  m2, 4
1037     psrldq  m3, 4
1038     movd  [P5], m0
1039     movd  [P1], m2
1040     movd  [Q2], m1
1041     movd  [Q6], m3
1042     psrldq  m0, 4
1043     psrldq  m1, 4
1044     psrldq  m2, 4
1045     psrldq  m3, 4
1046     movd  [P4], m0
1047     movd  [P0], m2
1048     movd  [Q3], m1
1049     movd  [Q7], m3
1050 %else
1051     ; the following code do a transpose of 8 full lines to 16 half
1052     ; lines (high part). It is inlined to avoid the need of a staging area
1053     mova                    m0, [P3]
1054     mova                    m1, [P2]
1055     mova                    m2, [P1]
1056     mova                    m3, [P0]
1057     mova                    m4, [Q0]
1058     mova                    m5, [Q1]
1059 %if ARCH_X86_64
1060     mova                    m6, [Q2]
1061 %endif
1062     mova                    m7, [Q3]
1063     DEFINE_REAL_P7_TO_Q7
1064 %if ARCH_X86_64
1065     SBUTTERFLY  bw,  0,  1, 8
1066     SBUTTERFLY  bw,  2,  3, 8
1067     SBUTTERFLY  bw,  4,  5, 8
1068     SBUTTERFLY  bw,  6,  7, 8
1069     SBUTTERFLY  wd,  0,  2, 8
1070     SBUTTERFLY  wd,  1,  3, 8
1071     SBUTTERFLY  wd,  4,  6, 8
1072     SBUTTERFLY  wd,  5,  7, 8
1073     SBUTTERFLY  dq,  0,  4, 8
1074     SBUTTERFLY  dq,  1,  5, 8
1075     SBUTTERFLY  dq,  2,  6, 8
1076     SBUTTERFLY  dq,  3,  7, 8
1077 %else
1078     SBUTTERFLY  bw,  0,  1, 6
1079     mova  [rsp+64], m1
1080     mova        m6, [rsp+96]
1081     SBUTTERFLY  bw,  2,  3, 1
1082     SBUTTERFLY  bw,  4,  5, 1
1083     SBUTTERFLY  bw,  6,  7, 1
1084     SBUTTERFLY  wd,  0,  2, 1
1085     mova  [rsp+96], m2
1086     mova        m1, [rsp+64]
1087     SBUTTERFLY  wd,  1,  3, 2
1088     SBUTTERFLY  wd,  4,  6, 2
1089     SBUTTERFLY  wd,  5,  7, 2
1090     SBUTTERFLY  dq,  0,  4, 2
1091     SBUTTERFLY  dq,  1,  5, 2
1092     movh      [Q0], m1
1093     movhps    [Q1], m1
1094     mova        m2, [rsp+96]
1095     SBUTTERFLY  dq,  2,  6, 1
1096     SBUTTERFLY  dq,  3,  7, 1
1097 %endif
1098     SWAP         3, 6
1099     SWAP         1, 4
1100     movh      [P7], m0
1101     movhps    [P6], m0
1102     movh      [P5], m1
1103     movhps    [P4], m1
1104     movh      [P3], m2
1105     movhps    [P2], m2
1106     movh      [P1], m3
1107     movhps    [P0], m3
1108 %if ARCH_X86_64
1109     movh      [Q0], m4
1110     movhps    [Q1], m4
1111 %endif
1112     movh      [Q2], m5
1113     movhps    [Q3], m5
1114     movh      [Q4], m6
1115     movhps    [Q5], m6
1116     movh      [Q6], m7
1117     movhps    [Q7], m7
1118 %endif
1119 %endif
1120
1121     RET
1122 %endmacro
1123
1124 %macro LPF_16_VH 5
1125 INIT_XMM %5
1126 LOOPFILTER v, %1, %2,  0, %4
1127 LOOPFILTER h, %1, %2, %3, %4
1128 %endmacro
1129
1130 %macro LPF_16_VH_ALL_OPTS 4
1131 LPF_16_VH %1, %2, %3, %4, sse2
1132 LPF_16_VH %1, %2, %3, %4, ssse3
1133 LPF_16_VH %1, %2, %3, %4, avx
1134 %endmacro
1135
1136 LPF_16_VH_ALL_OPTS 16, 512, 256, 32
1137 LPF_16_VH_ALL_OPTS 44,   0, 128,  0
1138 LPF_16_VH_ALL_OPTS 48, 256, 128, 16
1139 LPF_16_VH_ALL_OPTS 84, 256, 128, 16
1140 LPF_16_VH_ALL_OPTS 88, 256, 128, 16