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