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