]> git.sesse.net Git - x264/blob - common/x86/x86util.asm
cf827d236dfb926d0397ed16ff8f0f54b7ba691d
[x264] / common / x86 / x86util.asm
1 ;*****************************************************************************
2 ;* x86util.asm: x86 utility macros
3 ;*****************************************************************************
4 ;* Copyright (C) 2008-2010 x264 project
5 ;*
6 ;* Authors: Holger Lubitz <holger@lubitz.org>
7 ;*          Loren Merritt <lorenm@u.washington.edu>
8 ;*
9 ;* This program is free software; you can redistribute it and/or modify
10 ;* it under the terms of the GNU General Public License as published by
11 ;* the Free Software Foundation; either version 2 of the License, or
12 ;* (at your option) any later version.
13 ;*
14 ;* This program 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
17 ;* GNU General Public License for more details.
18 ;*
19 ;* You should have received a copy of the GNU General Public License
20 ;* along with this program; if not, write to the Free Software
21 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
22 ;*
23 ;* This program is also available under a commercial proprietary license.
24 ;* For more information, contact us at licensing@x264.com.
25 ;*****************************************************************************
26
27 %assign FENC_STRIDE 16
28 %assign FDEC_STRIDE 32
29
30 %assign SIZEOF_PIXEL 1
31 %assign SIZEOF_DCTCOEF 2
32 %ifdef X264_HIGH_BIT_DEPTH
33     %assign SIZEOF_PIXEL 2
34     %assign SIZEOF_DCTCOEF 4
35 %endif
36
37 %assign PIXEL_MAX ((1 << BIT_DEPTH)-1)
38
39 %macro SBUTTERFLY 4
40     mova      m%4, m%2
41     punpckl%1 m%2, m%3
42     punpckh%1 m%4, m%3
43     SWAP %3, %4
44 %endmacro
45
46 %macro SBUTTERFLY2 4
47     mova      m%4, m%2
48     punpckh%1 m%2, m%3
49     punpckl%1 m%4, m%3
50     SWAP %2, %4, %3
51 %endmacro
52
53 %macro TRANSPOSE4x4W 5
54     SBUTTERFLY wd, %1, %2, %5
55     SBUTTERFLY wd, %3, %4, %5
56     SBUTTERFLY dq, %1, %3, %5
57     SBUTTERFLY dq, %2, %4, %5
58     SWAP %2, %3
59 %endmacro
60
61 %macro TRANSPOSE2x4x4W 5
62     SBUTTERFLY wd,  %1, %2, %5
63     SBUTTERFLY wd,  %3, %4, %5
64     SBUTTERFLY dq,  %1, %3, %5
65     SBUTTERFLY dq,  %2, %4, %5
66     SBUTTERFLY qdq, %1, %2, %5
67     SBUTTERFLY qdq, %3, %4, %5
68 %endmacro
69
70 %macro TRANSPOSE4x4D 5
71     SBUTTERFLY dq,  %1, %2, %5
72     SBUTTERFLY dq,  %3, %4, %5
73     SBUTTERFLY qdq, %1, %3, %5
74     SBUTTERFLY qdq, %2, %4, %5
75     SWAP %2, %3
76 %endmacro
77
78 %macro TRANSPOSE8x8W 9-11
79 %ifdef ARCH_X86_64
80     SBUTTERFLY wd,  %1, %2, %9
81     SBUTTERFLY wd,  %3, %4, %9
82     SBUTTERFLY wd,  %5, %6, %9
83     SBUTTERFLY wd,  %7, %8, %9
84     SBUTTERFLY dq,  %1, %3, %9
85     SBUTTERFLY dq,  %2, %4, %9
86     SBUTTERFLY dq,  %5, %7, %9
87     SBUTTERFLY dq,  %6, %8, %9
88     SBUTTERFLY qdq, %1, %5, %9
89     SBUTTERFLY qdq, %2, %6, %9
90     SBUTTERFLY qdq, %3, %7, %9
91     SBUTTERFLY qdq, %4, %8, %9
92     SWAP %2, %5
93     SWAP %4, %7
94 %else
95 ; in:  m0..m7, unless %11 in which case m6 is in %9
96 ; out: m0..m7, unless %11 in which case m4 is in %10
97 ; spills into %9 and %10
98 %if %0<11
99     movdqa %9, m%7
100 %endif
101     SBUTTERFLY wd,  %1, %2, %7
102     movdqa %10, m%2
103     movdqa m%7, %9
104     SBUTTERFLY wd,  %3, %4, %2
105     SBUTTERFLY wd,  %5, %6, %2
106     SBUTTERFLY wd,  %7, %8, %2
107     SBUTTERFLY dq,  %1, %3, %2
108     movdqa %9, m%3
109     movdqa m%2, %10
110     SBUTTERFLY dq,  %2, %4, %3
111     SBUTTERFLY dq,  %5, %7, %3
112     SBUTTERFLY dq,  %6, %8, %3
113     SBUTTERFLY qdq, %1, %5, %3
114     SBUTTERFLY qdq, %2, %6, %3
115     movdqa %10, m%2
116     movdqa m%3, %9
117     SBUTTERFLY qdq, %3, %7, %2
118     SBUTTERFLY qdq, %4, %8, %2
119     SWAP %2, %5
120     SWAP %4, %7
121 %if %0<11
122     movdqa m%5, %10
123 %endif
124 %endif
125 %endmacro
126
127 %macro ABS1_MMX 2    ; a, tmp
128     pxor    %2, %2
129     psubw   %2, %1
130     pmaxsw  %1, %2
131 %endmacro
132
133 %macro ABS2_MMX 4    ; a, b, tmp0, tmp1
134     pxor    %3, %3
135     pxor    %4, %4
136     psubw   %3, %1
137     psubw   %4, %2
138     pmaxsw  %1, %3
139     pmaxsw  %2, %4
140 %endmacro
141
142 %macro ABS1_SSSE3 2
143     pabsw   %1, %1
144 %endmacro
145
146 %macro ABS2_SSSE3 4
147     pabsw   %1, %1
148     pabsw   %2, %2
149 %endmacro
150
151 %macro ABSB_MMX 2
152     pxor    %2, %2
153     psubb   %2, %1
154     pminub  %1, %2
155 %endmacro
156
157 %macro ABSB2_MMX 4
158     pxor    %3, %3
159     pxor    %4, %4
160     psubb   %3, %1
161     psubb   %4, %2
162     pminub  %1, %3
163     pminub  %2, %4
164 %endmacro
165
166 %macro ABSD2_MMX 4
167     pxor    %3, %3
168     pxor    %4, %4
169     pcmpgtd %3, %1
170     pcmpgtd %4, %2
171     pxor    %1, %3
172     pxor    %2, %4
173     psubd   %1, %3
174     psubd   %2, %4
175 %endmacro
176
177 %macro ABSB_SSSE3 2
178     pabsb   %1, %1
179 %endmacro
180
181 %macro ABSB2_SSSE3 4
182     pabsb   %1, %1
183     pabsb   %2, %2
184 %endmacro
185
186 %macro ABS4 6
187     ABS2 %1, %2, %5, %6
188     ABS2 %3, %4, %5, %6
189 %endmacro
190
191 %define ABS1 ABS1_MMX
192 %define ABS2 ABS2_MMX
193 %define ABSB ABSB_MMX
194 %define ABSB2 ABSB2_MMX
195
196 %macro SPLATB_MMX 3
197     movd      %1, [%2-3] ;to avoid crossing a cacheline
198     punpcklbw %1, %1
199 %if mmsize==16
200     pshuflw   %1, %1, 0xff
201     punpcklqdq %1, %1
202 %else
203     pshufw    %1, %1, 0xff
204 %endif
205 %endmacro
206
207 %macro SPLATB_SSSE3 3
208     movd      %1, [%2-3]
209     pshufb    %1, %3
210 %endmacro
211
212 %macro PALIGNR_MMX 4
213     %ifnidn %4, %2
214     mova    %4, %2
215     %endif
216     %if mmsize == 8
217     psllq   %1, (8-%3)*8
218     psrlq   %4, %3*8
219     %else
220     pslldq  %1, 16-%3
221     psrldq  %4, %3
222     %endif
223     por     %1, %4
224 %endmacro
225
226 %macro PALIGNR_SSSE3 4
227     palignr %1, %2, %3
228 %endmacro
229
230 %macro DEINTB 5 ; mask, reg1, mask, reg2, optional src to fill masks from
231 %ifnum %5
232     mova   m%1, m%5
233     mova   m%3, m%5
234 %else
235     mova   m%1, %5
236     mova   m%3, m%1
237 %endif
238     pand   m%1, m%2 ; dst .. y6 .. y4
239     pand   m%3, m%4 ; src .. y6 .. y4
240     psrlw  m%2, 8   ; dst .. y7 .. y5
241     psrlw  m%4, 8   ; src .. y7 .. y5
242 %endmacro
243
244 %macro SUMSUB_BA 2-3
245 %if %0==2
246     paddw   %1, %2
247     paddw   %2, %2
248     psubw   %2, %1
249 %else
250     mova    %3, %1
251     paddw   %1, %2
252     psubw   %2, %3
253 %endif
254 %endmacro
255
256 %macro SUMSUB_BADC 4-5
257 %if %0==5
258     SUMSUB_BA %1, %2, %5
259     SUMSUB_BA %3, %4, %5
260 %else
261     paddw   %1, %2
262     paddw   %3, %4
263     paddw   %2, %2
264     paddw   %4, %4
265     psubw   %2, %1
266     psubw   %4, %3
267 %endif
268 %endmacro
269
270 %macro HADAMARD4_V 4+
271     SUMSUB_BADC %1, %2, %3, %4
272     SUMSUB_BADC %1, %3, %2, %4
273 %endmacro
274
275 %macro HADAMARD8_V 8+
276     SUMSUB_BADC %1, %2, %3, %4
277     SUMSUB_BADC %5, %6, %7, %8
278     SUMSUB_BADC %1, %3, %2, %4
279     SUMSUB_BADC %5, %7, %6, %8
280     SUMSUB_BADC %1, %5, %2, %6
281     SUMSUB_BADC %3, %7, %4, %8
282 %endmacro
283
284 %macro TRANS_SSE2 5-6
285 ; TRANSPOSE2x2
286 ; %1: transpose width (d/q) - use SBUTTERFLY qdq for dq
287 ; %2: ord/unord (for compat with sse4, unused)
288 ; %3/%4: source regs
289 ; %5/%6: tmp regs
290 %ifidn %1, d
291 %define mask [mask_10]
292 %define shift 16
293 %elifidn %1, q
294 %define mask [mask_1100]
295 %define shift 32
296 %endif
297 %if %0==6 ; less dependency if we have two tmp
298     mova   m%5, mask   ; ff00
299     mova   m%6, m%4    ; x5x4
300     psll%1 m%4, shift  ; x4..
301     pand   m%6, m%5    ; x5..
302     pandn  m%5, m%3    ; ..x0
303     psrl%1 m%3, shift  ; ..x1
304     por    m%4, m%5    ; x4x0
305     por    m%3, m%6    ; x5x1
306 %else ; more dependency, one insn less. sometimes faster, sometimes not
307     mova   m%5, m%4    ; x5x4
308     psll%1 m%4, shift  ; x4..
309     pxor   m%4, m%3    ; (x4^x1)x0
310     pand   m%4, mask   ; (x4^x1)..
311     pxor   m%3, m%4    ; x4x0
312     psrl%1 m%4, shift  ; ..(x1^x4)
313     pxor   m%5, m%4    ; x5x1
314     SWAP   %4, %3, %5
315 %endif
316 %endmacro
317
318 %macro TRANS_SSE4 5-6 ; see above
319 %ifidn %1, d
320     mova   m%5, m%3
321 %ifidn %2, ord
322     psrl%1 m%3, 16
323 %endif
324     pblendw m%3, m%4, 10101010b
325     psll%1 m%4, 16
326 %ifidn %2, ord
327     pblendw m%4, m%5, 01010101b
328 %else
329     psrl%1 m%5, 16
330     por    m%4, m%5
331 %endif
332 %elifidn %1, q
333     mova   m%5, m%3
334     shufps m%3, m%4, 10001000b
335     shufps m%5, m%4, 11011101b
336     SWAP   %4, %5
337 %endif
338 %endmacro
339
340 %macro HADAMARD 5-6
341 ; %1=distance in words (0 for vertical pass, 1/2/4 for horizontal passes)
342 ; %2=sumsub/max/amax (sum and diff / maximum / maximum of absolutes)
343 ; %3/%4: regs
344 ; %5(%6): tmpregs
345 %if %1!=0 ; have to reorder stuff for horizontal op
346     %ifidn %2, sumsub
347          %define ORDER ord
348          ; sumsub needs order because a-b != b-a unless a=b
349     %else
350          %define ORDER unord
351          ; if we just max, order doesn't matter (allows pblendw+or in sse4)
352     %endif
353     %if %1==1
354          TRANS d, ORDER, %3, %4, %5, %6
355     %elif %1==2
356          %if mmsize==8
357              SBUTTERFLY dq, %3, %4, %5
358          %else
359              TRANS q, ORDER, %3, %4, %5, %6
360          %endif
361     %elif %1==4
362          SBUTTERFLY qdq, %3, %4, %5
363     %endif
364 %endif
365 %ifidn %2, sumsub
366     SUMSUB_BA m%3, m%4, m%5
367 %else
368     %ifidn %2, amax
369         %if %0==6
370             ABS2 m%3, m%4, m%5, m%6
371         %else
372             ABS1 m%3, m%5
373             ABS1 m%4, m%5
374         %endif
375     %endif
376     pmaxsw m%3, m%4
377 %endif
378 %endmacro
379
380
381 %macro HADAMARD2_2D 6-7 sumsub
382     HADAMARD 0, sumsub, %1, %2, %5
383     HADAMARD 0, sumsub, %3, %4, %5
384     SBUTTERFLY %6, %1, %2, %5
385 %ifnum %7
386     HADAMARD 0, amax, %1, %2, %5, %7
387 %else
388     HADAMARD 0, %7, %1, %2, %5
389 %endif
390     SBUTTERFLY %6, %3, %4, %5
391 %ifnum %7
392     HADAMARD 0, amax, %3, %4, %5, %7
393 %else
394     HADAMARD 0, %7, %3, %4, %5
395 %endif
396 %endmacro
397
398 %macro HADAMARD4_2D 5-6 sumsub
399     HADAMARD2_2D %1, %2, %3, %4, %5, wd
400     HADAMARD2_2D %1, %3, %2, %4, %5, dq, %6
401     SWAP %2, %3
402 %endmacro
403
404 %macro HADAMARD4_2D_SSE 5-6 sumsub
405     HADAMARD  0, sumsub, %1, %2, %5 ; 1st V row 0 + 1
406     HADAMARD  0, sumsub, %3, %4, %5 ; 1st V row 2 + 3
407     SBUTTERFLY   wd, %1, %2, %5     ; %1: m0 1+0 %2: m1 1+0
408     SBUTTERFLY   wd, %3, %4, %5     ; %3: m0 3+2 %4: m1 3+2
409     HADAMARD2_2D %1, %3, %2, %4, %5, dq
410     SBUTTERFLY  qdq, %1, %2, %5
411     HADAMARD  0, %6, %1, %2, %5     ; 2nd H m1/m0 row 0+1
412     SBUTTERFLY  qdq, %3, %4, %5
413     HADAMARD  0, %6, %3, %4, %5     ; 2nd H m1/m0 row 2+3
414 %endmacro
415
416 %macro HADAMARD8_2D 9-10 sumsub
417     HADAMARD2_2D %1, %2, %3, %4, %9, wd
418     HADAMARD2_2D %5, %6, %7, %8, %9, wd
419     HADAMARD2_2D %1, %3, %2, %4, %9, dq
420     HADAMARD2_2D %5, %7, %6, %8, %9, dq
421     HADAMARD2_2D %1, %5, %3, %7, %9, qdq, %10
422     HADAMARD2_2D %2, %6, %4, %8, %9, qdq, %10
423 %ifnidn %10, amax
424     SWAP %2, %5
425     SWAP %4, %7
426 %endif
427 %endmacro
428
429 %macro SUMSUB2_AB 3
430     mova    %3, %1
431     paddw   %1, %1
432     paddw   %1, %2
433     psubw   %3, %2
434     psubw   %3, %2
435 %endmacro
436
437 %macro SUMSUB2_BA 3
438     mova    m%3, m%1
439     paddw   m%1, m%2
440     paddw   m%1, m%2
441     psubw   m%2, m%3
442     psubw   m%2, m%3
443 %endmacro
444
445 %macro SUMSUBD2_AB 4
446     mova    %4, %1
447     mova    %3, %2
448     psraw   %2, 1  ; %2: %2>>1
449     psraw   %1, 1  ; %1: %1>>1
450     paddw   %2, %4 ; %2: %2>>1+%1
451     psubw   %1, %3 ; %1: %1>>1-%2
452 %endmacro
453
454 %macro DCT4_1D 5
455 %ifnum %5
456     SUMSUB_BADC m%4, m%1, m%3, m%2; m%5
457     SUMSUB_BA   m%3, m%4, m%5
458     SUMSUB2_AB  m%1, m%2, m%5
459     SWAP %1, %3, %4, %5, %2
460 %else
461     SUMSUB_BADC m%4, m%1, m%3, m%2
462     SUMSUB_BA   m%3, m%4
463     mova       [%5], m%2
464     SUMSUB2_AB m%1, [%5], m%2
465     SWAP %1, %3, %4, %2
466 %endif
467 %endmacro
468
469 %macro IDCT4_1D 5-6
470 %ifnum %5
471     SUMSUBD2_AB m%2, m%4, m%6, m%5
472     ; %2: %2>>1-%4 %4: %2+%4>>1
473     SUMSUB_BA   m%3, m%1, m%6
474     ; %3: %1+%3 %1: %1-%3
475     SUMSUB_BADC m%4, m%3, m%2, m%1, m%6
476     ; %4: %1+%3 + (%2+%4>>1)
477     ; %3: %1+%3 - (%2+%4>>1)
478     ; %2: %1-%3 + (%2>>1-%4)
479     ; %1: %1-%3 - (%2>>1-%4)
480 %else
481     SUMSUBD2_AB m%2, m%4, [%5], [%5+16]
482     SUMSUB_BA   m%3, m%1
483     SUMSUB_BADC m%4, m%3, m%2, m%1
484 %endif
485     SWAP %1, %4, %3
486     ; %1: %1+%3 + (%2+%4>>1) row0
487     ; %2: %1-%3 + (%2>>1-%4) row1
488     ; %3: %1-%3 - (%2>>1-%4) row2
489     ; %4: %1+%3 - (%2+%4>>1) row3
490 %endmacro
491
492
493 %macro LOAD_DIFF 5
494 %ifdef X264_HIGH_BIT_DEPTH
495     mova       %1, %4
496     psubw      %1, %5
497 %elifidn %3, none
498     movh       %1, %4
499     movh       %2, %5
500     punpcklbw  %1, %2
501     punpcklbw  %2, %2
502     psubw      %1, %2
503 %else
504     movh       %1, %4
505     punpcklbw  %1, %3
506     movh       %2, %5
507     punpcklbw  %2, %3
508     psubw      %1, %2
509 %endif
510 %endmacro
511
512 %macro LOAD_DIFF8x4_SSE2 8
513     LOAD_DIFF  m%1, m%5, m%6, [%7+%1*FENC_STRIDE], [%8+%1*FDEC_STRIDE]
514     LOAD_DIFF  m%2, m%5, m%6, [%7+%2*FENC_STRIDE], [%8+%2*FDEC_STRIDE]
515     LOAD_DIFF  m%3, m%5, m%6, [%7+%3*FENC_STRIDE], [%8+%3*FDEC_STRIDE]
516     LOAD_DIFF  m%4, m%5, m%6, [%7+%4*FENC_STRIDE], [%8+%4*FDEC_STRIDE]
517 %endmacro
518
519 %macro LOAD_DIFF8x4_SSSE3 8 ; 4x dst, 1x tmp, 1x mul, 2x ptr
520     movh       m%2, [%8+%1*FDEC_STRIDE]
521     movh       m%1, [%7+%1*FENC_STRIDE]
522     punpcklbw  m%1, m%2
523     movh       m%3, [%8+%2*FDEC_STRIDE]
524     movh       m%2, [%7+%2*FENC_STRIDE]
525     punpcklbw  m%2, m%3
526     movh       m%4, [%8+%3*FDEC_STRIDE]
527     movh       m%3, [%7+%3*FENC_STRIDE]
528     punpcklbw  m%3, m%4
529     movh       m%5, [%8+%4*FDEC_STRIDE]
530     movh       m%4, [%7+%4*FENC_STRIDE]
531     punpcklbw  m%4, m%5
532     pmaddubsw  m%1, m%6
533     pmaddubsw  m%2, m%6
534     pmaddubsw  m%3, m%6
535     pmaddubsw  m%4, m%6
536 %endmacro
537
538 %macro STORE_DCT 6
539     movq   [%5+%6+ 0], m%1
540     movq   [%5+%6+ 8], m%2
541     movq   [%5+%6+16], m%3
542     movq   [%5+%6+24], m%4
543     movhps [%5+%6+32], m%1
544     movhps [%5+%6+40], m%2
545     movhps [%5+%6+48], m%3
546     movhps [%5+%6+56], m%4
547 %endmacro
548
549 %macro STORE_IDCT 4
550     movhps [r0-4*FDEC_STRIDE], %1
551     movh   [r0-3*FDEC_STRIDE], %1
552     movhps [r0-2*FDEC_STRIDE], %2
553     movh   [r0-1*FDEC_STRIDE], %2
554     movhps [r0+0*FDEC_STRIDE], %3
555     movh   [r0+1*FDEC_STRIDE], %3
556     movhps [r0+2*FDEC_STRIDE], %4
557     movh   [r0+3*FDEC_STRIDE], %4
558 %endmacro
559
560 %macro LOAD_DIFF_8x4P 7-10 r0,r2,0 ; 4x dest, 2x temp, 2x pointer, increment?
561     LOAD_DIFF m%1, m%5, m%7, [%8],      [%9]
562     LOAD_DIFF m%2, m%6, m%7, [%8+r1],   [%9+r3]
563     LOAD_DIFF m%3, m%5, m%7, [%8+2*r1], [%9+2*r3]
564     LOAD_DIFF m%4, m%6, m%7, [%8+r4],   [%9+r5]
565 %if %10
566     lea %8, [%8+4*r1]
567     lea %9, [%9+4*r3]
568 %endif
569 %endmacro
570
571 %macro DIFFx2 6-7
572     movh       %3, %5
573     punpcklbw  %3, %4
574     psraw      %1, 6
575     paddsw     %1, %3
576     movh       %3, %6
577     punpcklbw  %3, %4
578     psraw      %2, 6
579     paddsw     %2, %3
580     packuswb   %2, %1
581 %endmacro
582
583 %ifdef X264_HIGH_BIT_DEPTH
584 %macro STORE_DIFF 5
585     punpcklwd  %2, %1
586     punpckhwd  %3, %1
587     psrad      %2, 16
588     psrad      %3, 16
589     mova       %4, %2
590     mova       %5, %3
591 %endmacro
592 %else
593 %macro STORE_DIFF 4
594     movh       %2, %4
595     punpcklbw  %2, %3
596     psraw      %1, 6
597     paddsw     %1, %2
598     packuswb   %1, %1
599     movh       %4, %1
600 %endmacro
601 %endif
602
603 %macro CLIPW 3 ;(dst, min, max)
604     pmaxsw %1, %2
605     pminsw %1, %3
606 %endmacro
607
608 %macro FIX_STRIDES 1-*
609 %ifdef X264_HIGH_BIT_DEPTH
610 %rep %0
611     add %1, %1
612     %rotate 1
613 %endrep
614 %endif
615 %endmacro
616
617 %macro SPLATW 2-3 0
618 %if mmsize == 16
619     pshuflw    %1, %2, %3*0x55
620     punpcklqdq %1, %1
621 %else
622     pshufw     %1, %2, %3*0x55
623 %endif
624 %endmacro
625
626 %macro SPLATD 2-3 0
627 %if mmsize == 16
628     pshufd %1, %2, %3*0x55
629 %else
630     pshufw %1, %2, %3*0x11 + (%3+1)*0x44
631 %endif
632 %endmacro