]> git.sesse.net Git - ffmpeg/blob - libavcodec/x86/lossless_videodsp.asm
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / x86 / lossless_videodsp.asm
1 ;******************************************************************************
2 ;* SIMD lossless video DSP utils
3 ;* Copyright (c) 2008 Loren Merritt
4 ;* Copyright (c) 2014 Michael Niedermayer
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_RODATA
26
27 pb_ef: times 8 db 14,15
28 pb_67: times 8 db  6, 7
29 pb_zzzz2323zzzzabab: db -1,-1,-1,-1, 2, 3, 2, 3,-1,-1,-1,-1,10,11,10,11
30 pb_zzzzzzzz67676767: db -1,-1,-1,-1,-1,-1,-1,-1, 6, 7, 6, 7, 6, 7, 6, 7
31
32 SECTION_TEXT
33
34 %macro INT16_LOOP 2 ; %1 = a/u (aligned/unaligned), %2 = add/sub
35     movd    m4, maskd
36     SPLATW  m4, m4
37     add     wd, wd
38     test    wq, 2*mmsize - 1
39     jz %%.tomainloop
40 %%.wordloop:
41     sub     wq, 2
42 %ifidn %2, add
43     mov     ax, [srcq+wq]
44     add     ax, [dstq+wq]
45 %else
46     mov     ax, [src1q+wq]
47     sub     ax, [src2q+wq]
48 %endif
49     and     ax, maskw
50     mov     [dstq+wq], ax
51     test    wq, 2*mmsize - 1
52     jnz %%.wordloop
53 %%.tomainloop:
54 %ifidn %2, add
55     add     srcq, wq
56 %else
57     add     src1q, wq
58     add     src2q, wq
59 %endif
60     add     dstq, wq
61     neg     wq
62     jz      %%.end
63 %%.loop:
64 %ifidn %2, add
65     mov%1   m0, [srcq+wq]
66     mov%1   m1, [dstq+wq]
67     mov%1   m2, [srcq+wq+mmsize]
68     mov%1   m3, [dstq+wq+mmsize]
69 %else
70     mov%1   m0, [src1q+wq]
71     mov%1   m1, [src2q+wq]
72     mov%1   m2, [src1q+wq+mmsize]
73     mov%1   m3, [src2q+wq+mmsize]
74 %endif
75     p%2w    m0, m1
76     p%2w    m2, m3
77     pand    m0, m4
78     pand    m2, m4
79     mov%1   [dstq+wq]       , m0
80     mov%1   [dstq+wq+mmsize], m2
81     add     wq, 2*mmsize
82     jl %%.loop
83 %%.end:
84     RET
85 %endmacro
86
87 INIT_MMX mmx
88 cglobal add_int16, 4,4,5, dst, src, mask, w
89     INT16_LOOP a, add
90
91 INIT_XMM sse2
92 cglobal add_int16, 4,4,5, dst, src, mask, w
93     test srcq, mmsize-1
94     jnz .unaligned
95     test dstq, mmsize-1
96     jnz .unaligned
97     INT16_LOOP a, add
98 .unaligned:
99     INT16_LOOP u, add
100
101 INIT_MMX mmx
102 cglobal diff_int16, 5,5,5, dst, src1, src2, mask, w
103     INT16_LOOP a, sub
104
105 INIT_XMM sse2
106 cglobal diff_int16, 5,5,5, dst, src1, src2, mask, w
107     test src1q, mmsize-1
108     jnz .unaligned
109     test src2q, mmsize-1
110     jnz .unaligned
111     test dstq, mmsize-1
112     jnz .unaligned
113     INT16_LOOP a, sub
114 .unaligned:
115     INT16_LOOP u, sub
116
117
118 %macro ADD_HFYU_LEFT_LOOP_INT16 2 ; %1 = dst alignment (a/u), %2 = src alignment (a/u)
119     add     wd, wd
120     add     srcq, wq
121     add     dstq, wq
122     neg     wq
123 %%.loop:
124     mov%2   m1, [srcq+wq]
125     mova    m2, m1
126     pslld   m1, 16
127     paddw   m1, m2
128     mova    m2, m1
129
130     pshufb  m1, m3
131     paddw   m1, m2
132     pshufb  m0, m5
133 %if mmsize == 16
134     mova    m2, m1
135     pshufb  m1, m4
136     paddw   m1, m2
137 %endif
138     paddw   m0, m1
139     pand    m0, m7
140 %ifidn %1, a
141     mova    [dstq+wq], m0
142 %else
143     movq    [dstq+wq], m0
144     movhps  [dstq+wq+8], m0
145 %endif
146     add     wq, mmsize
147     jl %%.loop
148     mov     eax, mmsize-1
149     sub     eax, wd
150     mov     wd, eax
151     shl     wd, 8
152     lea     eax, [wd+eax-1]
153     movd    m1, eax
154     pshufb  m0, m1
155     movd    eax, m0
156     RET
157 %endmacro
158
159 ; int add_hfyu_left_prediction_int16(uint16_t *dst, const uint16_t *src, unsigned mask, int w, int left)
160 INIT_MMX ssse3
161 cglobal add_hfyu_left_prediction_int16, 4,4,8, dst, src, mask, w, left
162 .skip_prologue:
163     mova    m5, [pb_67]
164     mova    m3, [pb_zzzz2323zzzzabab]
165     movd    m0, leftm
166     psllq   m0, 48
167     movd    m7, maskm
168     SPLATW  m7 ,m7
169     ADD_HFYU_LEFT_LOOP_INT16 a, a
170
171 INIT_XMM sse4
172 cglobal add_hfyu_left_prediction_int16, 4,4,8, dst, src, mask, w, left
173     mova    m5, [pb_ef]
174     mova    m4, [pb_zzzzzzzz67676767]
175     mova    m3, [pb_zzzz2323zzzzabab]
176     movd    m0, leftm
177     pslldq  m0, 14
178     movd    m7, maskm
179     SPLATW  m7 ,m7
180     test    srcq, 15
181     jnz .src_unaligned
182     test    dstq, 15
183     jnz .dst_unaligned
184     ADD_HFYU_LEFT_LOOP_INT16 a, a
185 .dst_unaligned:
186     ADD_HFYU_LEFT_LOOP_INT16 u, a
187 .src_unaligned:
188     ADD_HFYU_LEFT_LOOP_INT16 u, u
189
190 ; 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)
191 INIT_MMX mmxext
192 cglobal add_hfyu_median_prediction_int16, 7,7,0, dst, top, diff, mask, w, left, left_top
193     add      wd, wd
194     movd    mm6, maskd
195     SPLATW  mm6, mm6
196     movq    mm0, [topq]
197     movq    mm2, mm0
198     movd    mm4, [left_topq]
199     psllq   mm2, 16
200     movq    mm1, mm0
201     por     mm4, mm2
202     movd    mm3, [leftq]
203     psubw   mm0, mm4 ; t-tl
204     add    dstq, wq
205     add    topq, wq
206     add   diffq, wq
207     neg      wq
208     jmp .skip
209 .loop:
210     movq    mm4, [topq+wq]
211     movq    mm0, mm4
212     psllq   mm4, 16
213     por     mm4, mm1
214     movq    mm1, mm0 ; t
215     psubw   mm0, mm4 ; t-tl
216 .skip:
217     movq    mm2, [diffq+wq]
218 %assign i 0
219 %rep 4
220     movq    mm4, mm0
221     paddw   mm4, mm3 ; t-tl+l
222     pand    mm4, mm6
223     movq    mm5, mm3
224     pmaxsw  mm3, mm1
225     pminsw  mm5, mm1
226     pminsw  mm3, mm4
227     pmaxsw  mm3, mm5 ; median
228     paddw   mm3, mm2 ; +residual
229     pand    mm3, mm6
230 %if i==0
231     movq    mm7, mm3
232     psllq   mm7, 48
233 %else
234     movq    mm4, mm3
235     psrlq   mm7, 16
236     psllq   mm4, 48
237     por     mm7, mm4
238 %endif
239 %if i<3
240     psrlq   mm0, 16
241     psrlq   mm1, 16
242     psrlq   mm2, 16
243 %endif
244 %assign i i+1
245 %endrep
246     movq [dstq+wq], mm7
247     add      wq, 8
248     jl .loop
249     movzx   r2d, word [dstq-2]
250     mov [leftq], r2d
251     movzx   r2d, word [topq-2]
252     mov [left_topq], r2d
253     RET
254
255 cglobal sub_hfyu_median_prediction_int16, 7,7,0, dst, src1, src2, mask, w, left, left_top
256     add      wd, wd
257     movd    mm7, maskd
258     SPLATW  mm7, mm7
259     movq    mm0, [src1q]
260     movq    mm2, [src2q]
261     psllq   mm0, 16
262     psllq   mm2, 16
263     movd    mm6, [left_topq]
264     por     mm0, mm6
265     movd    mm6, [leftq]
266     por     mm2, mm6
267     xor     maskq, maskq
268 .loop:
269     movq    mm1, [src1q + maskq]
270     movq    mm3, [src2q + maskq]
271     movq    mm4, mm2
272     psubw   mm2, mm0
273     paddw   mm2, mm1
274     pand    mm2, mm7
275     movq    mm5, mm4
276     pmaxsw  mm4, mm1
277     pminsw  mm1, mm5
278     pminsw  mm4, mm2
279     pmaxsw  mm4, mm1
280     psubw   mm3, mm4
281     pand    mm3, mm7
282     movq    [dstq + maskq], mm3
283     add     maskq, 8
284     movq    mm0, [src1q + maskq - 2]
285     movq    mm2, [src2q + maskq - 2]
286     cmp     maskq, wq
287         jb .loop
288     mov maskd, [src1q + wq - 2]
289     mov [left_topq], maskd
290     mov maskd, [src2q + wq - 2]
291     mov [leftq], maskd
292     RET