]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/huffyuvdsp.asm
Merge commit '0e0538aefc75958ded49f5d075c99a81cf6b2bbb'
[ffmpeg] / libavcodec / x86 / huffyuvdsp.asm
1 ;******************************************************************************
2 ;* SIMD-optimized HuffYUV functions
3 ;* Copyright (c) 2008 Loren Merritt
4 ;* Copyright (c) 2014 Christophe Gisquet
5 ;*
6 ;* This file is part of FFmpeg.
7 ;*
8 ;* FFmpeg is free software; you can redistribute it and/or
9 ;* modify it under the terms of the GNU Lesser General Public
10 ;* License as published by the Free Software Foundation; either
11 ;* version 2.1 of the License, or (at your option) any later version.
12 ;*
13 ;* FFmpeg is distributed in the hope that it will be useful,
14 ;* but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 ;* Lesser General Public License for more details.
17 ;*
18 ;* You should have received a copy of the GNU Lesser General Public
19 ;* License along with FFmpeg; if not, write to the Free Software
20 ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 ;******************************************************************************
22
23 %include "libavutil/x86/x86util.asm"
24
25 SECTION .text
26
27
28 %macro INT16_LOOP 2 ; %1 = a/u (aligned/unaligned), %2 = add/sub
29     movd    m4, maskd
30     SPLATW  m4, m4
31     add     wd, wd
32     test    wq, 2*mmsize - 1
33     jz %%.tomainloop
34     push  tmpq
35 %%.wordloop:
36     sub     wq, 2
37 %ifidn %2, add
38     mov   tmpw, [srcq+wq]
39     add   tmpw, [dstq+wq]
40 %else
41     mov   tmpw, [src1q+wq]
42     sub   tmpw, [src2q+wq]
43 %endif
44     and   tmpw, maskw
45     mov     [dstq+wq], tmpw
46     test    wq, 2*mmsize - 1
47     jnz %%.wordloop
48     pop   tmpq
49 %%.tomainloop:
50 %ifidn %2, add
51     add     srcq, wq
52 %else
53     add     src1q, wq
54     add     src2q, wq
55 %endif
56     add     dstq, wq
57     neg     wq
58     jz      %%.end
59 %%.loop:
60 %ifidn %2, add
61     mov%1   m0, [srcq+wq]
62     mov%1   m1, [dstq+wq]
63     mov%1   m2, [srcq+wq+mmsize]
64     mov%1   m3, [dstq+wq+mmsize]
65 %else
66     mov%1   m0, [src1q+wq]
67     mov%1   m1, [src2q+wq]
68     mov%1   m2, [src1q+wq+mmsize]
69     mov%1   m3, [src2q+wq+mmsize]
70 %endif
71     p%2w    m0, m1
72     p%2w    m2, m3
73     pand    m0, m4
74     pand    m2, m4
75     mov%1   [dstq+wq]       , m0
76     mov%1   [dstq+wq+mmsize], m2
77     add     wq, 2*mmsize
78     jl %%.loop
79 %%.end:
80     RET
81 %endmacro
82
83 %if ARCH_X86_32
84 INIT_MMX mmx
85 cglobal add_int16, 4,4,5, dst, src, mask, w, tmp
86     INT16_LOOP a, add
87 %endif
88
89 INIT_XMM sse2
90 cglobal add_int16, 4,4,5, dst, src, mask, w, tmp
91     test srcq, mmsize-1
92     jnz .unaligned
93     test dstq, mmsize-1
94     jnz .unaligned
95     INT16_LOOP a, add
96 .unaligned:
97     INT16_LOOP u, add
98
99 ; void add_hfyu_left_pred_bgr32(uint8_t *dst, const uint8_t *src,
100 ;                               intptr_t w, uint8_t *left)
101 %macro LEFT_BGR32 0
102 cglobal add_hfyu_left_pred_bgr32, 4,4,3, dst, src, w, left
103     shl           wq, 2
104     movd          m0, [leftq]
105     lea         dstq, [dstq + wq]
106     lea         srcq, [srcq + wq]
107     LSHIFT        m0, mmsize-4
108     neg           wq
109 .loop:
110     movu          m1, [srcq+wq]
111     mova          m2, m1
112 %if mmsize == 8
113     punpckhdq     m0, m0
114 %endif
115     LSHIFT        m1, 4
116     paddb         m1, m2
117 %if mmsize == 16
118     pshufd        m0, m0, q3333
119     mova          m2, m1
120     LSHIFT        m1, 8
121     paddb         m1, m2
122 %endif
123     paddb         m0, m1
124     movu   [dstq+wq], m0
125     add           wq, mmsize
126     jl         .loop
127     movd          m0, [dstq-4]
128     movd     [leftq], m0
129     REP_RET
130 %endmacro
131
132 %if ARCH_X86_32
133 INIT_MMX mmx
134 LEFT_BGR32
135 %endif
136 INIT_XMM sse2
137 LEFT_BGR32
138
139 ; void add_hfyu_median_prediction_mmxext(uint8_t *dst, const uint8_t *top, const uint8_t *diff, int mask, int w, int *left, int *left_top)
140 INIT_MMX mmxext
141 cglobal add_hfyu_median_pred_int16, 7,7,0, dst, top, diff, mask, w, left, left_top
142     add      wd, wd
143     movd    mm6, maskd
144     SPLATW  mm6, mm6
145     movq    mm0, [topq]
146     movq    mm2, mm0
147     movd    mm4, [left_topq]
148     psllq   mm2, 16
149     movq    mm1, mm0
150     por     mm4, mm2
151     movd    mm3, [leftq]
152     psubw   mm0, mm4 ; t-tl
153     add    dstq, wq
154     add    topq, wq
155     add   diffq, wq
156     neg      wq
157     jmp .skip
158 .loop:
159     movq    mm4, [topq+wq]
160     movq    mm0, mm4
161     psllq   mm4, 16
162     por     mm4, mm1
163     movq    mm1, mm0 ; t
164     psubw   mm0, mm4 ; t-tl
165 .skip:
166     movq    mm2, [diffq+wq]
167 %assign i 0
168 %rep 4
169     movq    mm4, mm0
170     paddw   mm4, mm3 ; t-tl+l
171     pand    mm4, mm6
172     movq    mm5, mm3
173     pmaxsw  mm3, mm1
174     pminsw  mm5, mm1
175     pminsw  mm3, mm4
176     pmaxsw  mm3, mm5 ; median
177     paddw   mm3, mm2 ; +residual
178     pand    mm3, mm6
179 %if i==0
180     movq    mm7, mm3
181     psllq   mm7, 48
182 %else
183     movq    mm4, mm3
184     psrlq   mm7, 16
185     psllq   mm4, 48
186     por     mm7, mm4
187 %endif
188 %if i<3
189     psrlq   mm0, 16
190     psrlq   mm1, 16
191     psrlq   mm2, 16
192 %endif
193 %assign i i+1
194 %endrep
195     movq [dstq+wq], mm7
196     add      wq, 8
197     jl .loop
198     movzx   r2d, word [dstq-2]
199     mov [leftq], r2d
200     movzx   r2d, word [topq-2]
201     mov [left_topq], r2d
202     RET